Go 知识点(05)— 类型别名与类型定义

1. 类型别名

类型别名需要在别名和原类型之间加上赋值符号 = ,使用类型别名定义的类型与原类型等价,Go 语言内建的基本类型中就存在两个别名类型。

  • byteuint8 的别名类型;
  • runeint32 的别名类型;

类型别名定义形式如下:

type MyString = string

上面代码表明 MyStringstring 类型的别名类型。也就是说别名类型和源类型表示的是同一个目标,就譬如每个人的学名和乳名一样,都表示同一个人。

定义 string 类型的别名,示例代码:

func main() {
	type MyString = string
	str := "hello"
	a := MyString(str)
	b := MyString("A" + str)
	fmt.Printf("str type is %T\n", str)
	fmt.Printf("a type is %T\n", a)
	fmt.Printf("a == str is %t\n", a == str)
	fmt.Printf("b > a is %t\n", b > a)
}

输出结果

str type is string
a type is string
a == str is true
b > a is false

定义 []string 类型的别名,示例代码:

func main() {
	type MyString = string
	strs := []string{"aa", "bb", "cc"}
	a := []MyString(strs)

	fmt.Printf("strs type is %T\n", strs)
	fmt.Printf("a type is %T\n", a)
	fmt.Printf("a == nil is %t\n", a == nil)
	fmt.Printf("strs == nil is %t\n", strs != nil)
}

运行结果为:

strs type is []string
a type is []string
a == nil is false
strs == nil is true

从上面结果可以得出以下结论:

  • 别名类型与源类型是完全相同的;
  • 别名类型与源类型可以在源类型支持的条件下进行相等判断、比较判断、与 nil 是否相等判断等;

2. 类型定义

类型定义是定义一种新的类型,它与源类型是不一样的。看下面代码:


func main() {
	type MyString string
	str := "hello"
	a := MyString(str)
	b := MyString("A" + str)
	fmt.Printf("str type is %T\n", str)
	fmt.Printf("a type is %T\n", a)
	fmt.Printf("a value is %#v\n", a)
	fmt.Printf("b value is %#v\n", b)
	// fmt.Printf("a == str is %t\n", a == str)
	fmt.Printf("b > a is %t\n", b > a)
}

输出结果为:

str type is string
a type is main.MyString
a value is "hello"
b value is "Ahello"
b > a is false

可以看到 MyString 类型为 main.MyString 而原有的 str 类型为 string,两者是不同的类型,如果使用下面的判断相等语句

fmt.Printf("a == str is %t\n", a == str)

会有编译错误提示

invalid operation: a == str (mismatched types MyString and string)

说明类型不匹配。

下面代码

func main() {
	type MyString string

	strs := []string{"E", "F", "G"}
	myStrs := []MyString(strs)
	fmt.Println(myStrs)
}

编译报错提示

cannot convert strs (type []string) to type []MyString

类型定义与别名

对于这里的类型再定义来说,string 可以被称为 MyString2 的潜在类型。潜在类型的含义是,某个类型在本质上是哪个类型。潜在类型相同的不同类型的值之间是可以进行类型转换的。

因此,MyString2 类型的值与 string 类型的值可以使用类型转换表达式进行互转。但对于集合类的类型[]MyString2[]string 来说这样做却是不合法的,因为 []MyString2[]string 的潜在类型不同,分别是 []MyString2[]string

另外,即使两个不同类型的潜在类型相同,它们的值之间也不能进行判等或比较,它们的变量之间也不能赋值。

func main() {
	type MyString1 = string
	type MyString2 string
	str := "BCD"
	myStr1 := MyString1(str)
	myStr2 := MyString2(str)
	myStr1 = MyString1(myStr2)
	myStr2 = MyString2(myStr1)

	myStr1 = str

	myStr2 = str
	// cannot use str (type string) as type MyString2 in assignment

	myStr1 = myStr2
	// cannot use myStr2 (type MyString2) as type string in assignment

	myStr2 = myStr1
	// cannot use myStr1 (type string) as type MyString2 in assignment
}

参考:
https://time.geekbang.org/column/article/13601

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值