Форум программистов, компьютерный форум, киберфорум
Go (Golang)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
 Аватар для voraa
1259 / 1211 / 180
Регистрация: 21.01.2024
Сообщений: 5,576

Объясните тип any. Как с ним работать?

29.02.2024, 19:02. Показов 1165. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите разобраться с типом any
Был такой код
Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type struct Block {
//
}
 
blocks:= make(map[int]*Block)
 
func GetBlock (n int) *Block {
    block, ok := blocks[n]
    if !ok {
        block = new(Block)
        // как то заполняем его
        blocks[n] = block
    }
    return block
}
Когда пришел черед горутин, разумеется полезли ошибки.
Прочитал про sync.Map

Пытался сделать так

Go
1
2
3
4
5
6
7
8
9
10
11
var blocks sync.Map
 
func GetBlock (n int) *Block {
    block, ok := blocks.Load(n) // Но block будет иметь тип any
    if !ok {
        block = new(Block)  // block все равно any
        // Заполнить не удается. block.prop = x нельзя сделать
        blocks.Store(n, block)
    }
    return block   // И как вернуть именно *Block? Так (*Block)(bl) - не получается
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.02.2024, 19:02
Ответы с готовыми решениями:

Объясните что такое fetch_assoc() и как с ним работать
При работе скрипта выходит ошибка: Неустранимая ошибка: вызов функции-члена fetch_assoc() на bool in /srv / disk19 / 3334503 / www /...

Текстовый тип PAnsiChar - как с ним работать ?
что то не соображу никак где ошибка ? беру текст из мемо и не получаю текста на выходе ! причем строку в мемо вижу, вижу что ушли...

Неизвестный BLE тип девайса под 10й виндой - как с ним работать?
Добрый вечер уважаемые форумчане. Есть некое ble устройство с известным мне форматом сигнала. Винда(устроит, кстати любая -но учитывая...

14
364 / 328 / 83
Регистрация: 17.04.2022
Сообщений: 1,080
Записей в блоге: 8
29.02.2024, 19:11
Лучший ответ Сообщение было отмечено voraa как решение

Решение

Цитата Сообщение от voraa Посмотреть сообщение
Объясните тип any. Как с ним работать?
Подозреваю, что вы интересуетесь этим -
https://go.dev/tour/methods/15
https://go.dev/tour/methods/16
1
 Аватар для voraa
1259 / 1211 / 180
Регистрация: 21.01.2024
Сообщений: 5,576
29.02.2024, 19:22  [ТС]
Т.е. надо
Go
1
2
3
4
5
6
7
8
9
10
11
12
var blocks sync.Map
 
func GetBlock (n int) *Block {
    block, ok := blocks.Load(n) // Но block будет иметь тип any
    b:=block.(*Block) // b - *Block
    if !ok {
        b = new(Block)  
        // Заполняем *b
        blocks.Store(n, b)
    }
    return b 
}
Похоже так сработает
Спасибо
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
01.03.2024, 15:23
voraa, так будет паника, если не ok.

Добавлено через 6 минут
И всё равно GetBlock не потокобезопасна. Две горутины могут такой функцией записать два разных Block для одного и того же n.
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
01.03.2024, 15:57
...

0
 Аватар для voraa
1259 / 1211 / 180
Регистрация: 21.01.2024
Сообщений: 5,576
01.03.2024, 17:35  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
так будет паника, если не ok.
А разве не так?

Go
1
2
    block, ok := blocks.Load(n) // Если не ok, то в block будет nil.
    b:=block.(*Block) // b нулевой указатель *Block
Цитата Сообщение от korvin_ Посмотреть сообщение
всё равно GetBlock не потокобезопасна. Две горутины могут такой функцией записать два разных Block для одного и того же n.
Спасибо. Похоже есть проблема
А такое решение? (Спрашиваю, т.к опыта маловато)
Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var blocks = make(map[int32](*Block))
var mu sync.Mutex
 
func GetBlock (n int) *Block {
    mu.Lock()
    block, ok := blocks[n] 
    if !ok {
        block = new(Block)  
        // Заполняем *block
        blocks[n] = block
    }
    mu.Unlock()
    return block 
}
0
364 / 328 / 83
Регистрация: 17.04.2022
Сообщений: 1,080
Записей в блоге: 8
01.03.2024, 18:51
1) В глаза бросается mu.Unlock() в конце. Прввильней так
Go
1
2
3
mu.Lock()
defer mu.Unlock()
...
2) В структуру Block надо тоже добавить mutex и все модификации экземпляра тоже защищать через Lock/Unlock
0
 Аватар для voraa
1259 / 1211 / 180
Регистрация: 21.01.2024
Сообщений: 5,576
01.03.2024, 20:17  [ТС]
Цитата Сообщение от sqltd1 Посмотреть сообщение
В глаза бросается mu.Unlock() в конце. Прввильней так
А в чем принципиальная разница. Выход то у функции один.
Цитата Сообщение от sqltd1 Посмотреть сообщение
В структуру Block надо тоже добавить mutex и все модификации экземпляра тоже защищать через Lock/Unlock
В моей задаче этого не требуется. Они не модифицируются. Из них только берутся данные.

На самом деле это решение мне не очень нравится. Заполнение нового блока - длительная операция - там идет считывание из файла. Считывается блок один раз, а разные горутины могут обращаться к считанным блокам много раз. И когда какая то горутина блокирует, что бы считать какой то блок, то другие уже не могут обращаться к уже считанным.
blocks - это некий хеш.

Вот думаю про такое решение.

Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var blocks = make([]*Block, maxblocs)
var mu sync.Mutex
 
func GetBlock (n int) *Block {
 
    block := blocks[n] 
    if block != nil { return block}
    
    mu.Lock()
    defer mu.Unlock()
    block = blocks[n] 
    if block != nil {   // А вдруг он появился, пока была блокировка
    return block
    }
    block = new(Block)  
    // Заполняем *block
    blocks[n] = block
    return block 
}
Ведь другие горутины смогут выполнять первые строчки, до mu.Lock()?
Я правильно понимаю?
0
364 / 328 / 83
Регистрация: 17.04.2022
Сообщений: 1,080
Записей в блоге: 8
01.03.2024, 20:54
Цитата Сообщение от voraa Посмотреть сообщение
А в чем принципиальная разница. Выход то у функции один.
defer mu.Unlock() сразу после mu.Lock() гарантирует снятие блокировки при возникновении аварийных ситуаций в теле функции. У меня это уже рефлекторно, особенно полезно если несколько точек завершения.

Как мне кажется, строки 6-7 не нужны

должна быть проверка 0<=n<maxblocks
0
 Аватар для voraa
1259 / 1211 / 180
Регистрация: 21.01.2024
Сообщений: 5,576
01.03.2024, 21:15  [ТС]
Цитата Сообщение от sqltd1 Посмотреть сообщение
должна быть проверка 0<=n<maxblocks
Там при вызовах проверки. И если они успешны, а такого блока нет, то не понятно, что делать дальше. Конечно при считывании блока, если его не существует, это все равно фатальная ошибка. Такого быть не должно.
Цитата Сообщение от sqltd1 Посмотреть сообщение
Как мне кажется, строки 6-7 не нужны
В них то все и дело, если я правильно понимаю, как работает mutex.Lock/Unlock.
Допустим горутина хочет получит блок 10, которого нет. она проходит строчки 6-7 потом блокирует код, начиная со строки 9. Как я понимаю, блокировка говорит, что другие горутины не могут одновременно с первой выполнять код после 9 строчки. Они, дойдя до нее будут ждать, когда блокировка будет снята. Но если другой горутине понадобится блок 5, который уже есть, она благополучно выполнит код из строк 6-7 и получит свой блок, пока первая горутина считывает свой 10й блок.
Иначе ей тоже придется ждать, пока первая не считает свой.

Или все работает совсем не так?
0
364 / 328 / 83
Регистрация: 17.04.2022
Сообщений: 1,080
Записей в блоге: 8
01.03.2024, 22:14
Вы правы, не обратил внимания на ваше предыдущее замечание о том, что создание блока - "тяжелая" операция.
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
02.03.2024, 11:02
Цитата Сообщение от voraa Посмотреть сообщение
А разве не так?
Что?
0
 Аватар для voraa
1259 / 1211 / 180
Регистрация: 21.01.2024
Сообщений: 5,576
02.03.2024, 12:09  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
Что?
Ну я там в том посте код привел с комментариями, объясняющий, что паники не будет

Реализовал код из поста 8.
Собрал небольшую статистику.
На запросе было 126 обращений к GetBlock
В 16 случаях было считывание с диска.
Но в 5 случаях, как раз возникала ситуация, когда горутина требовала блок, но изначально его не было, и ей приходилось ждать окончания блокировки. И после этого, он там появлялся (строки 11-14)
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
02.03.2024, 13:40
Цитата Сообщение от voraa Посмотреть сообщение
А разве не так?
Go
1
b:=block.(*Block) // b нулевой указатель *Block
Не так. block — нулевой указатель any. Я же тебе ссылку на код в go.dev/play скинул в том посте, открой, запусти и увидишь панику.
0
 Аватар для voraa
1259 / 1211 / 180
Регистрация: 21.01.2024
Сообщений: 5,576
02.03.2024, 13:50  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
Не так. block — нулевой указатель any.
Ясно
Я думал что нулевой указатель тоже можно так преобразовывать.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.03.2024, 13:50
Помогаю со студенческими работами здесь

Where и как с ним работать?
не могу разобраться с расширением Where на майкрофте пишут int numbers = { 0, 30, 20, 15, 90, 85, 40, 75 }; ...

ПакетЗапросов как с ним работать?
имеется пакет запросов, я его выполняю, получаю массив.Как работать с элементами этого массива? логично было бы предположить что так: ...

Прокси как с ним работать?
Кто, что сможет подскажите как использовать в VB прокси. Нужно чтобы ICQ использовался через прокси. Можете скинуть на...

DaraGridView - как с ним работать
Вот кусок кода в котором я получаю нужные данные (переменная result), записываю в двумерный массив mResult = result;. Хочу получить...

Iif как с ним работать?
Добрый день, форумчане) Имеется задача: Если значение в Поле7 равно 5, то в Поле 10 необходимо вставить значение &quot;300*2&quot;,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru