2015-10-28 2 views
1

Я учусь Go (как это до сих пор), но у меня возникла интересная проблема. Код, который не может скомпилировать это:Функциональные вызовы, назначение и «базовые типы» в Go

package main 

import "fmt" 

type MyInt int 

func (i MyInt) Double() MyInt { 
    return i + i 
} 

func AddTwo(i int) int { 
    return i + 2 
} 

func main() { 
    var a int = 3 
    var x MyInt = a // Why does this fail? 
    fmt.Println(x.Double()) 
    var y int = AddTwo(x) // Why does this fail? 
    fmt.Println(y) 
} 

Вот ссылка Go площадка: MyInt

Когда я пытаюсь запустить это, я получаю следующие ошибки:

prog.go:17: cannot use a (type int) as type MyInt in assignment 
    prog.go:19: cannot use x (type MyInt) as type int in argument to AddTwo 

Однако, если я «Я правильно читаю спецификацию, этот код должен компилироваться. Прежде всего, базовый тип MyInt - intaccording to this section. Фактически, один из приведенных примеров - type T1 string, и он говорит, что базовый тип T1 равен string. Так почему я не могу назначить a на x? Разве они не имеют одного и того же базового типа? То же самое касается вызова функции на AddTwo(). Не имеется x имеет базовый тип int? Почему я не могу использовать его как аргумент int?

Также, как получается, Double() компилируется? В выражении i + i Я добавляю два значения MyInt. Тот факт, что он компилирует, предполагает, что MyIntявляется a int хотя бы в некотором смысле.

Во всяком случае, я немного смущен. Поэтому я думал, что точка объявлений вроде type MyInt int заключается в том, что теперь вы можете добавлять методы к примитивным типам. Но если вы потеряете способность относиться к ним как к int (нужно сделать бросок), то в чем смысл всего этого бизнеса «базового типа»?

ответ

5

Go имеет строгую систему типов. Просто потому, что ваш тип является просто псевдонимом для int, не означает, что вы можете свободно их менять, вам все равно придется преобразовывать тип. Ниже приведена рабочая версия вашего основного, вот код на игровой площадке; https://play.golang.org/p/kdVY145lrJ

func main() { 
    var a int = 3 
    var x MyInt = MyInt(a) // Why does this fail? 
    fmt.Println(x.Double()) 
    var y int = AddTwo(int(x)) // Why does this fail? 
    fmt.Println(y) 
} 
+1

Тогда почему Double() компилируется в первую очередь? Как я могу добавить (используя оператор «+») два значения MyInt? О, и, между прочим, означает ли это бокс/распаковка значений MyInt в/из значений int? –

+2

Разрешение и назначение метода @LajosNagy соответствуют различным правилам, назначение более строгое. Если у вас есть два значения «MyInt», вы можете добавить их так же, как и два значения «int», однако вы не можете добавить 'int' и' MyInt' без преобразования типов, потому что он скажет «несоответствующие типы», , пример здесь; https://play.golang.org/p/KNqdbqGpfd Мне нужно было бы прочитать спецификацию, чтобы дать разумное объяснение того, как разрешено разрешение метода в Go, поэтому я думаю, что вам лучше было бы разобраться в этом сами. Я просто избегаю ситуаций, которые требуют чего-то большего, чем здравый смысл, чтобы знать, что произойдет. – evanmcdonnal

+0

Извините, еще одна вещь: знаете ли вы, что Go использует бокс/unboxing для MyInt? Я имею в виду, это размер int или нет? (Это может иметь значение, если есть затраты на использование MyInt вместо int.) –

Смежные вопросы