【Go自学】一文搞懂Go中Type关键字的用法

我们一般在定义结构体和接口时会经常使用type关键字,本文会总结golang中type关键字的五种用法。

1、定义结构体

2、定义接口

3、定义函数类型

4、定义类型别名

5、i.(type)类型查询


一、定义结构体

结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。

结构体表示一项记录,比如保存图书馆的书籍记录,每本书有以下属性:

type Books struct {
   title string
   author string
   subject string
   book_id int
}

可以将结构体理解为面向对象编程中类的属性部分,用了定义类的属性,并保存数据


二、定义接口 

Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。

接口可以让我们将不同的类型绑定到一组公共的方法上,从而实现多态和灵活的设计。

Go 语言中的接口是隐式实现的,也就是说,如果一个类型实现了一个接口定义的所有方法,那么它就自动地实现了该接口。因此,我们可以通过将接口作为参数来实现对不同类型的调用,从而实现多态。

/* 定义接口 */
type interface_name interface {
   method_name1 [return_type]
   method_name2 [return_type]
   method_name3 [return_type]
   ...
   method_namen [return_type]
}

/* 定义结构体 */
type struct_name struct {
   /* variables */
}

/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {
   /* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
   /* 方法实现*/
}

更多有关接口的知识请见Go中的接口的定义与实现;接口类型 


三、定义函数类型

再开始学习之前我们首先复习下函数的定义

func function_name( [parameter list] ) [return_types] {
   函数体
}

函数类型相同

两个函数类型相同的条件是:拥有相同的形参列表和返回值列表(列表元素的次序、个数和类型都相同),形参名可以不同 。 以下 3 个函数的函数类型完全一样。

func add (a , b int) int { return a + b }
func sub (c int, d int) int { return c - d }
func mul (e int, f int) int { return e * f }
  • 举个栗子
    新建test.go
package main
import "fmt"

func add(a, b int) int     { return a + b }
func sub(c int, d int) int { return c - d }
func mul(e int, f int) int { return e * f }

func main() {
	fmt.Printf("%T\n", add)
	fmt.Printf("%T\n", sub)
	fmt.Printf("%T\n", mul)
}

执行go run test.go输出结果如下:

func(int, int) int
func(int, int) int
func(int, int) int

通过type定义函数类型

通过 type 可以定义函数类型,格式如下

type typeName func(arguments) retType

函数类型也是一种类型,故可以将其定义为函数入参,在 go 语言中函数名可以看做是函数类型的常量,所以我们可以直接将函数名作为参数传入的函数中。

package main

import "fmt"

func add(a, b int) int {
	return a + b
}

//sub作为函数名可以看成是 op 类型的常量
func sub(a, b int) int {
	return a - b
}

//定义函数类型 op
type op func(a, b int) int

//形参指定传入参数为函数类型op
func Oper(fu op, a, b int) int {
	return fu(a, b)
}

func main() {
	//在go语言中函数名可以看做是函数类型的常量,所以我们可以直接将函数名作为参数传入的函数中。
	aa := Oper(add, 1, 2)
	fmt.Println(aa)
	bb := Oper(sub, 1, 2)
	fmt.Println(bb)
}

 四、定义别名

实际上byte类型是int8类型的别名,rune类型是int32类型的别名,需要注意的是类型别名与原类型是两种类型,不能直接操作,需要进行类型转换。

package main

import "fmt"

// 定义类型别名
type 字符串 = string
​
func main() {
  // 声明类型别名变量
  var str 字符串
  // 变量赋值
  str = "这是中文"
  // 打印数据类型和值
  fmt.Printf("type is %T, value is %v\n", str, str)
}

五、 i.(type)

数据类型的判断,有一个方式通过i.(type)结合空接口实现,注意的是该写法必须与switch case联合使用,case中列出实现该接口的类型。示例代码如下

​// 实现数据类型的判断
func checkType(i interface{}) string {
  switch i.(type) {
  case string:
    return "string"
  case int:
    return "int"
  case float64:
    return "float64"
  default:
    return "unknown"
  }
}
​
func main() {
  // 验证
  v1 := "hello world"
  v2 := 33
  v3 := 45.2
  fmt.Printf("the type of v1 is %s\n", checkType(v1))
  fmt.Printf("the type of v2 is %s\n", checkType(v2))
  fmt.Printf("the type of v3 is %s\n", checkType(v3))
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Weber77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值