Custom type

There are some basic data types in Go, such as string, integer, floating point, Boolean, etc. In Go, you can use the type keyword to define custom types.

Type is an important and commonly used keyword in Go syntax, and type is not just corresponding to typedef in C/C++. If you understand the use of type, you can easily understand the use of core concepts such as struct, interface, and function in go.

The type definition

Defining structure

Use type to define the structure type:

//1
// Struct definition
type person struct {
   name string // Make sure there is no comma after it
   age  int
}
Copy the code

Defines the interface

Use type to define the interface type:

type USB interface {
	start()
	end()
}
Copy the code

Define additional new types

With type, you can also define new types.

Grammar:

typeType name, Type,Copy the code

Sample code:

type myint int
type mystr string

func main(a) {

	 var i1 myint
	 var i2 = 100
	 i1 = 100
	 fmt.Println(i1)
	 //i1 = i2 //cannot use i2 (type int) as type myint in assignment
	 fmt.Println(i1,i2)
	 
	 var name mystr
	 name = "King two Dogs"
	 var s1 string
	 s1 = "Li Xiaohua"
	 fmt.Println(name)
	 fmt.Println(s1)
	 name = s1 //cannot use s1 (type string) as type mystr in assignment
}
Copy the code

Define the type of the function

The Go language supports functional programming and can use high-level programming syntax. A function can be used as an argument to another function or as a return value of another function. When defining a higher-order function, if the type of the function is more complex, you can use type to define the type of the function:

func main(a) {
	 res1 := fun1()
	 fmt.Println(res1(10.20))}type my_fun  func (int.int)(string)

// the fun1() function returns a value of type my_func
func fun1 (a) my_fun{
	fun := func(a,b int) string {
		s := strconv.Itoa(a) + strconv.Itoa(b)
		return s
	}
	return fun
}
Copy the code

Type the alias

Type aliasing states that TypeAlias is simply an alias of Type, and TypeAlias is essentially the same Type as Type. For example, when a child has a nickname, a baby name, after school with a scientific name, The English teacher will give him An English name, but these names refer to him.

Type aliasing is a new feature added in the Go 1.9 release. Mainly used for code upgrade, migration type compatibility problems. In C/C++, code refactoring upgrades can use macros to quickly define a new piece of code. Instead of opting for macros, Go will address the most troublesome type name changes in refactoring.

type TypeAlias = Type
Copy the code

The code for built-in type definitions prior to Go 1.9 looks like this:

type byte uint8
type rune int32
Copy the code

After Go 1.9, it changed to:

type byte = uint8
type rune = int32
Copy the code

This change is made in conjunction with the type alias.

Difference between a type definition and a type alias

The following code illustrates the apparent difference between a type alias and a type definition with just an equal sign.

// Type definition
type NewInt int

// Type alias
type MyInt = int

func main(a) {
	var a NewInt
	var b MyInt
	
	fmt.Printf("type of a:%T\n", a) //type of a:main.NewInt
	fmt.Printf("type of b:%T\n", b) //type of b:int
}
Copy the code

The result shows that the type of a is main.NewInt, which represents the NewInt type defined under the main package. B is of type int. The MyInt type only exists in the code, and does not exist when the compilation is complete.

Non-native types cannot define methods

Does being able to name types at will mean that you can add any method you want to those types in your own package?

// Alias time.Duration to MyDuration
type MyDuration = time.Duration
// Add a function to MyDuration
func (m MyDuration) EasySet(a string) { //cannot define new methods on non-local type time.Duration
}
func main(a){}Copy the code

The above code reported an error. Cannot define new methods on non-local type time.Duration

Compiler warning: new methods cannot be defined on a non-local type time.Duration. Non-local methods refer to the package in which the code that uses time.duration resides, which is the main package. Because time.Duration is defined in the time package, it is used in the main package. The time.Duration package is not in the same package as the main package, so you cannot define methods for types that are not in the same package.

There are two ways to solve this problem:

  • Change the type alias to a type definition:type MyDuration time.Duration, that is, willMyDurationChange from alias to type.
  • willMyDurationThe alias definition is placed intimeIn the package.

Alias names are used when structure members are embedded

What happens when a type alias is an embedded member of a structure?

type Person struct {
	name string
}

func (p Person) Show(a) {
	fmt.Println("Person-->",p.name)
}

// Type alias
type People = Person

type Student struct {
	// Embed two structures
	Person
	People
}

func (p People) Show2(a){
	fmt.Println("People------>",p.name)
}

func main(a) {
	//
	var s Student

	// unambiguous selector s.name.unambiguous
	s.People.name = "Li Xiaohua"
	s.Person.name = "King two Dogs"
	//s.Show() //ambiguous selector s.Show
	s.Person.Show()
	s.People.Show2()
	fmt.Printf("%T,%T\n",s.Person,s.People) //main.Person,main.Person

}
Copy the code

When s calls name directly, or when S calls the Show() method directly, because both types have the name field and Show() method, there is ambiguity, proving that People is indeed a Person type by nature.