go 语言关键字 type

type 关键字定义的新数据类型可以基于 Go 语言内置的基本数据类型,也可以基于 struct 类型来定义。

自定义类型

定义一种新的数据类型的语法为:

type 新数据类型  基于的数据类型

类型别名

在 Go 语言中,type 关键字还可以定义一个类型别名,语法如下:

type 别名 = 数据类型

自定义类型与类型别名的区别

对于自定义类型,其类型和其基于的类型不相同。
而类型别名,其类型和其基于的类型相同。

如下代码:

/*
type name string 自定义类型,类型不相同
type name = string 类型别名,类型相同
*/


type name = string
func Demo1() {
	 fmt.Println("demo1================")
	 var myname name = "Jack"
	 myname2 := myname
	 fmt.Printf("%T \n", myname2)
	 fmt.Printf("%v \n", myname2 == "Jack")
	 myname3 := "Jack"

     // true 类型别名,如果是自定义类型, myname2 和 myname3的类型不相同
	 fmt.Printf("%t \n", myname2 == myname3)
     var t byte //uint8 的别名
     fmt.Printf("%T \n",t)
     var a rune   //int32 的别名
     fmt.Printf("%T \n",a)
}

自定义类型与基础类型

自定义类型可以与基础类型进行运算,但是和其他自定义内部不能直接运算。

package main

import "fmt"

// 加仑
type Gallons float64

// 升
type Liters float64

func main1() {
	gallons := Gallons(20.0)
	liters := Liters(10.0)
	// 即使其使用的基础类型都是float64,但是不能直接赋值
	gallons = Gallons(liters)

	// 自定义类型可以与基础类型进行运算,但是和其他自定义内部不能直接运算
	// fmt.Println(gallons + liters)  //mismatched types Gallons and Liters
	fmt.Println(gallons + 3.14)
	fmt.Println(gallons + Gallons(liters))

}

自定义类型与方法接收器

自定义类型可以作为方法的接收器参数类型。

就像任何的函数参数一样,你需要提供一个接收器参数的名称,后面跟着类型。

但是就像其他任何参数,接收器参数接收一个接收器的拷贝值。如果你使用方法来修改接收器,你修改的是拷贝,而不是原始值。

type Number int

func (n *Number) toDouble() {
	*n *= 2
}

func main() {
	number := Number(4)
	number.toDouble() // 8
	fmt.Println("after Double==", number)
	f := &number
	f.toDouble() // 16
	fmt.Println("after Double==", number)

}

当你用一个非指针的变量调用一个需要指针的接收器的方法的时候,Go 会自动为你将非指针类型转换为指针类型。

同样指针类型也会自动转换为非指针类型,如果你调用一个要求值类型的接收器,Go 会自动帮你获取指针指向的值,然后传递给方法。

本章知识要点

  • 一旦你定义了类型。你可以从相同基础类型转换:
Gallons(10.0)
  • 一旦一个变量的类型被定义,其他类型的值不能再赋给该变量,即使它们有相同的基础类型。
  • 一个定义的类型支持与基础类型相同的运算符。例如一个基于 int 的类型,能够支持+、-、*、/、==、>和<运算符。
  • 一个定义的类型可以与字面值一起运算:
Gallons(10.0) + 2.3
  • 在函数名称前放入一个在括号中的接收器参数来定义一个方法:
func (m MyType) MyMethod() {
}
  • 接收器参数可以像其他参数一样在方法内部被调用:
func (m MyType) MyMethod() {
      fmt.Println("called on", m)
}
  • 与函数一样,你可以为方法定义一个额外的参数或者返回值。
  • 在同一个包中定义多个同名的函数不被允许,即使它们有不同类型的参数。你可以定义多个相同名字的方法,只要它们分别属于不同的类型。
  • 你只能为同包的类型定义方法。
  • 就像其他的参数一样,接收器参数接收一个原值的拷贝。如果你的方法需要修改接收器,你应该在接收器参数上使用指针类型,并且修改指针指向的值。