2014-09-07 3 views
0
package main 

import "fmt" 

type Number int 

func (n *Number) IncreaseMe(i int) { 
     *n += i 
} 

func main() { 
     n := Number(10) 

     n.IncreaseMe(90) // n is now supposed to be 100 

     fmt.Println(n) 
} 

При выполнении кода выше, это дает мне сообщение об ошибкеGo: Введите утверждения в structs?

недопустимая операция: * п + = я (несовпадающие типы Number и INT)

Что следует ожидать, как он пытается выполнить математическую операцию над переменными, которые не имеют одного и того же типа.

Затем я попытался

*n.(int) += i 

который сообщает компилятору не беспокоиться, как * п можно смело трактовать как целое число, что приводит меня к

invalid type assertion: n.(int) (non-interface type *Number on left) 

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

Какое решение для этого?

ответ

5

Как уже упоминалось в "Go: Named type assertions and conversions"

Тип утверждение работает только для интерфейсов. Интерфейс может иметь произвольный базовый тип, поэтому у нас есть тип assertion и type switch для спасения.

Вам не нужно утверждение типа: вы можете просто:

  • обращенного *n к int: int(*n) (так как вы знаете, очень хорошо, фактический тип).
  • сделать добавление
  • преобразовать обратно в Number

    *n = Number(int(*n) + i) 
    

Смотрите это play.golang.org: выход 100.


Как ruakh упоминает in the comments:

Go разделяет концепцию «литья» на два отдельных понятия:

  • один («преобразования типов») для преобразования, что компилятор знает правильно, и
  • один («типа утверждений») для которые должны быть проверены во время выполнения.

Последнее относится только к интерфейсам, поскольку только интерфейсы имеют дополнительную информацию о типе во время выполнения, что не известно во время компиляции.

+4

+1.Другими словами, Go разбивает концепцию «кастинг» на две отдельные концепции: одна («преобразования типов») для преобразований, которые компилятор знает, правильные, и один («утверждения типа») для преобразований, которые необходимо проверять во время выполнения. Последнее относится только к интерфейсам, поскольку только интерфейсы имеют дополнительную информацию о типе во время выполнения, что не известно во время компиляции. – ruakh

+1

@ruakh хорошая точка. Я включил ваш комментарий в ответ для большей наглядности. – VonC

+0

(@ruakh, люблю описание, никогда не слышал, чтобы это было так) – twotwotwo