0%

golang 基础 - 关于使用Type定义类型的几个问题

从一道题目开始入手Type的一些具体知识,可以想想打印结果是什么?

这里涉及到的是一些golang语言中的Type的一些基础知识,不要再犯迷糊了,好好地加深一下认识~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import (
"fmt"
)
// 1--
type T interface{}
// 2--
type X string
// 3--
type Y = string

func main() {
var t T = "abc"
var x X = "abc"
var y Y = "abc"

fmt.Println(t == x)
fmt.Println(t == string(x))

fmt.Println(t == y)
fmt.Println(t == string(y))
}

输出结果如下:

1
2
3
4
false
true
true
true

不知道你是不是跟我一样错了两个,上面涉及的知识点接下来一一展开~

在第7、9、11行中:

  1. 第7行, 使用type定义自定义类型T, 底层为interface接口类型
  2. 第9行, 使用type定义自定义类型X, 底层为string,X 和 string 是不同的类型!
  3. 第11行, 使用type申明类型别名Y, 为string类型的别名,Y和 string 是一样的!

通过上面的Type我们可以了解到,Type有两种格式:申明别名 和 定义类型

需要注意的是使用type定义的所有类型(非类型别名)都是不同的, 如:

  • type A string
  • type B string
  • type C string

那么A, B, C 的类型是不同的!

在第14、15、16行中:申明特定类型的变量, 并使用各类型的字面值进行赋值(不同类型的字面值可能不一样),但是T、X 和 Y 虽然都赋值为字符串 abc,但含义不一样:

  1. T 是空接口,可以存放任意类型值;

  2. X 的底层类型是 string,因此字符串字面量 abc 可以直接赋值给 x

    • 但下面的情况是不允许的:

      • var s string = var s string = "abc"
        var x X = s
        
  3. Y 是 string 的别名,自然可以直接赋值

接下来涉及到了比较了,先说明接口类型值和非接口类型值比较的一些问题:

Go 语言规范里有这样的说明:

A value x of non-interface type X and a value t of interface type T are comparable when values of type X are comparable and X implements T. They are equal if t’s dynamic type is identical to X and t’s dynamic value is equal to x.

翻译如下:

当非接口类型 X 的值是可比较的且 X 实现了接口类型 T ,那么 X 的值 xT 的值 t 是可比较的。如果 t的动态类型和 X 一致并且 t 的动态值等于 x 的话,那么它们相等。

那么再对题目进行细细解剖:

第18行为什么输出false?

  • 这一行中, 接口值t的动态类型为string, 动态值为”abc”(第12行), 而非接口值x的类型为X, 类型都不相同, 动态值就不用比较了

第19行为什么输出true?

  • 把==号后面的值转换为string类型, 再与接口值t的动态类型和动态值比较, 类型相同, 值相等, 返回true

第21行为什么输出true?

  • 接口值t的动态类型和非接口值y的类型比较, 相同, 动态值与非接口值y的值比较, 相等, 返回true

第22行为什么输出true?

  • Y是string类型的别名, 所以string(y)和第19行的y一样, 都是string类型, 此行中的string()没有必要

至此,关于Type关键字的几个知识点应该可以了解到一些,还有对于接口类型值和非接口类型值比较应该也比较清晰了!