LINUX.ORG.RU

Нужно достать тип из переменной с nil значением

 


0

1

Вот, для примера набросал

http://play.golang.org/p/Gx-1LP_sq6

суть... по выхлопу этого небольшого примера видим, что даже при nil значении он умудряется понять, что тип *int32, но каким образом разименовать, чтобы получить просто int32?

Deleted

Ответ на: комментарий от Deleted

нужно определить тип, на который ссылается указатель в случае, когда значение указателя nil.

Deleted
()
Ответ на: комментарий от Deleted
var nnn *int32
var mmm *float32

nnn = mmm

код дает вот такую ошибку.

cannot use mmm (type *float32) as type *int32 in assignment

ибо го жестко типизирован (т.е. nil у переменной *int32 не то же самое, что и nil у переменной *float32).

А теперь представь, что между nnn и mmm есть IP протокол.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

нужно определить тип, на который ссылается указатель

Поскольку в Go статическая типизация, этот тип известен на этапе компиляции.

в случае, когда значение указателя nil

Тогда его нельзя разыменовать.

А теперь представь, что между nnn и mmm есть IP протокол.

Ну тогда надо знать, какого типа данные тебе пришли по сети и положить их в переменную нужного типа. Или ты хочешь, чтобы компилятор сам прочитал и осмыслил спецификацию сетевого протокола?

proud_anon ★★★★★
()
Ответ на: комментарий от proud_anon

Поскольку в Go статическая типизация, этот тип известен на этапе компиляции.

прочитай еще раз мой вопрос :)

вот тебе выхлоп рантайма при test(a), где а имеет тип *int32, однако значение nil

type pointer: <*int32 Value>
type pointer: invalid

Ну тогда надо знать, какого типа данные тебе пришли по сети и положить их в переменную нужного типа.

вот именно поэтому мне и нужно определить какой в оригинале тип должен быть, чтобы создать переменную нужного типа

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

Так глубоко ещё не нырял, но в чём проблема сравнить указатель на структуру с nil?

PS: из твоего суррогатного примера не ясно, что же тебе надо.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

мне без рефлекта по-любому не обойтись ибо нужно брать количество полей, их параметры (те же теги, например).

Deleted
()
Ответ на: комментарий от beastie

PS: из твоего суррогатного примера не ясно, что же тебе надо.

мне нужно из переменной, являющейся указателем на какой-то тип выдернуть идентификатор этого типа. другими словами, в рантайме прилетает какая-то структура, я должен пройтись по всем полям и понять, что есть какого типа. если это указатель, то я должен понять тип на что он указывает. даже в случае когда nil значение. в свое примере я показал, что в рантайме можно понять, что это *int32, но я хочу в чистом виде получить int32, чтобы отдать в одну функцию, которая знает, что нужно делать с таким типом.

Deleted
()
Ответ на: комментарий от Deleted

Теперь понятно, чего ты хочешь. Это невозможно. Тебе приходит по сети набор байт. Что к чему относится, рантайм никак определить не может.

Тебе нужно какое-то полноценное решение для сериализации. Например, можно посмотреть на пакет encoding из стандартной библиотеки: https://golang.org/pkg/encoding/

Или я всё ещё неправильно понимаю?

в свое примере я показал, что в рантайме можно понять, что это *int32, но я хочу в чистом виде получить int32, чтобы отдать в одну функцию, которая знает, что нужно делать с таким типом.

Если переменная типа *int32 содержит nil, то получить значение, на которое она ссылается, невозможно, потому что этого значения не существует. Но можно, например, написать:

var x int32
if ptrvar == nil {
    x = int32(0)
} else {
    x = *ptrvar
}

proud_anon ★★★★★
()
Последнее исправление: proud_anon (всего исправлений: 2)
Ответ на: комментарий от Deleted

в рантайме прилетает какая-то структура, я должен пройтись по всем полям и понять, что есть какого типа. если это указатель

Откуда?

Deleted
()
Ответ на: комментарий от netrino

Вот теперь оно! Спасибо большое.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.