Misunderstanding about 'type X Y' and auto cast

package main

//=========================================
type ArrStr []string

type S struct {
	as ArrStr
}

func (s *S) f() []string {
	s.as = s.f2() // A
	return s.as   // B
}

func (s *S) f2() []string {
	return make([]string, 0)
}

//==========================================
type Str string
type S2 struct {
	str Str
}

func (s *S2) f() string {
	s.str = s.f2() // C
	return s.str   // D
}

func (s *S2) f2() string {
	return ""
}

func main() {

}

why A,B is ok, but C,D is wrong ?

You can’t assign a string to Str because the underlying type of Str is []string. What behavior did you expect?

because you can’t assign a string to a []string.

sorry for misspelling.

# command-line-arguments
/playground/a6c0e93d07dd60f7392ccdf8b6f5ad51.go:26: cannot use s.f2() (type string) as type Str in assignment
/playground/a6c0e93d07dd60f7392ccdf8b6f5ad51.go:27: cannot use s.str (type Str) as type string in return argument

I hope A, B can’t be compiled too, but not just C, D

A and B are fine because ArrStr’s underlying type is []string and therefore it is casted from/to []string automatically

The key piece of information here are named and unnamed types, string is a named type, Str is also a named type, []string is not a named type, for the same reason that struct{ a, b int } is not a named type, or interface{} is not a named type. They are unnamed typed literals.

With this information you can consult the rules of type identity to answer the rest of the question.

3 Likes

thx. got it

The other piece of advice to remember is there are no automatic conversions between named types in Go, to the point that the word cast is not used in Go discourse.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.