Wednesday, 13 December 2017

go - Custom type passed to function as a parameter

itemprop="text">

When I define a custom type, it seems
that the type of the underlying type makes a difference about whether I can pass it to a
function as is or I need to convert it.



Question
is:

Why does RuneFunc and
StringMap work, but not
Integer?




href="https://play.golang.org/p/buKNkrg5y-"
rel="noreferrer">https://play.golang.org/p/buKNkrg5y-



package
main


type RuneFunc func(rune) rune
type
Integer int
type StringMap
map[string]string


func main() {
//m :=
make(StringMap)
//mf(m)


var i Integer =
5
nf(i)


//var f func(rune)
rune

//ff(f)

}

func
mf(i map[string]string) {

}
func ff(i func(rune)rune)
{

}

func nf(i int)
{

}


Here,
when I run this function called nf with
Integer it complains although int is
the underlying type. But when I call mf or
ff they run successfully.



Answer




Integer and
int



int
and your new type Integer are 2 different, distinct types.
Where Integer is expected, you have to pass a value of type
Integer.




If
you have an Integer value, you may use a simple type conversion
to make it a value of type int, because the underlying type of
Integer is
int:



var
i Integer =
5
nf(int(i))


What
may be confusing and interesting at the same time is that you are allowed to pass an
untyped constant without
conversion:



nf(5)



Try
these on the Go Playground.



The
reason for this is in the rel="nofollow noreferrer">Spec:
Assignability:





A value x is assignable to a
variable of type T
("x is assignable to T") in any of
these cases:




[...]






  • x is an untyped href="https://golang.org/ref/spec#Constants" rel="nofollow
    noreferrer">constant representable by a value of type
    T.





5
is an untyped constant which is representable by a value of type
int because the untyped constant 5 has
a default type int, so it is
representable by a value of type Integer (which has the same
default type).



If you check the other
assignability rules (not included in above quotation), none of them match the case where
you attempt to pass a value of Integer for the parameter of
type int, so that's not
allowed.




See related question: href="https://stackoverflow.com/questions/37385007/golang-creating-a-constant-type-and-restricting-the-types-values/37386119#37386119">Golang:
Creating a Constant Type and Restricting the Type's
Values



RuneFunc
and func(rune)
rune



The difference between this
case and the previous one (Integer and
int) is that int is a href="https://golang.org/ref/spec#Types" rel="nofollow noreferrer">named
type and func(rune) rune is
not.



And there's an assignability rule which
allows this:









So in this
case:



var f
RuneFunc
ff(f)


f
is a named type, but the parameter type of ff() is
func(rune) rune which is unnamed, so the assignment is
allowed.


No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...