Dans Go, si vous définissez un nouveau type, par exemple:
type MyInt int
Vous ne pouvez pas alors passer a MyInt
à une fonction qui attend un int, ou vice versa:
func test(i MyInt) {
//do something with i
}
func main() {
anInt := 0
test(anInt) //doesn't work, int is not of type MyInt
}
Bien. Mais pourquoi est-ce alors que la même chose ne s'applique pas aux fonctions? par exemple:
type MyFunc func(i int)
func (m MyFunc) Run(i int) {
m(i)
}
func run(f MyFunc, i int) {
f.Run(i)
}
func main() {
var newfunc func(int) //explicit declaration
newfunc = func(i int) {
fmt.Println(i)
}
run(newfunc, 10) //works just fine, even though types seem to differ
}
Maintenant, je ne me plains pas parce que cela m'évite d'avoir à faire un cast explicitement en newfunc
type MyFunc
, comme je devrais le faire dans le premier exemple; cela semble simplement incohérent. Je suis sûr qu'il y a une bonne raison à cela; quelqu'un peut-il m'éclairer?
La raison pour laquelle je pose la question est principalement parce que je voudrais raccourcir certains de mes types de fonctions plutôt longs de cette manière, mais je veux m'assurer que cela est attendu et acceptable :)
type
est plutôt plus utile dans Go que Scala. Scala n'a que des alias de type, hélas.Réponses:
Il s'avère que c'est un malentendu que j'avais sur la façon dont Go traitait les types, qui peut être résolu en lisant la partie pertinente de la spécification:
http://golang.org/ref/spec#Type_identity
La distinction pertinente que j'ignorais était celle des types nommés et non nommés .
Les types nommés sont des types avec un nom, tel que int, int64, float, string, bool. De plus, tout type que vous créez à l'aide de 'type' est un type nommé.
Les types sans nom sont ceux tels que [] string, map [string] string, [4] int. Ils n'ont pas de nom, simplement une description correspondant à la manière dont ils doivent être structurés.
Si vous comparez deux types nommés, les noms doivent correspondre pour qu'ils soient interchangeables. Si vous comparez un type nommé et un type sans nom, tant que la représentation sous-jacente correspond , vous êtes prêt à partir!
par exemple étant donné les types suivants:
ce qui suit n'est pas valide:
ce qui suit est très bien:
Je suis un peu vidé je ne savais pas ça plus tôt, alors j'espère que ça clarifie un peu le type alouette pour quelqu'un d'autre! Et cela signifie beaucoup moins de casting que je ne le pensais au début :)
la source
is := make(MySlice, 0); m := make(MyMap)
, qui est plus lisible dans certains contextes.La question et la réponse sont toutes deux assez éclairantes. Cependant, je voudrais faire une distinction qui n'est pas claire dans la réponse de Lytnus.
Le type nommé est différent du type sans nom .
La variable de type nommé peut être affectée à la variable de type sans nom , vice versa.
Une variable de type nommé différent ne peut pas être affectée l'une à l'autre.
http://play.golang.org/p/uaYHEnofT9
la source