go语言中的type是什么

go语言中的type是什么?可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

type是go语法里的重要而且常用的关键字,type绝不只是对应于C/C++中的typedef。type又有两种使用方式,一种是类型别名,一种是类型定义,是不是熟悉的C语言(define和typedef)味道?

类型定义

type Student struct {
  name String
  age int
}
type I int

类型别名

type Sdt = Student
type I = int

type有如下几种用法:

定义结构体

定义接口

类型定义

类型别名

类型查询

定义结构体

结构体是用户自定义的一种抽象的数据结构,golang中struct类似于java语言中的class, 在程序设计中,有着举足轻重的地位。结构体的用法,将会在struct关键字中详细的介绍。下边来看一下定义一个结构体的语法格式:

type name struct {
    Field1  dataType
    Field2  dataType
    Field3  dataType
}

定义接口

接口相关知识点,将会在interface关键字中详细介绍,下边来看一段定义接口的语法格式:

type name interface{
    Read()
    Write()
}

类型定义

使用类型定义定义出来的类型与原类型不相同,所以不能使用新类型变量赋值给原类型变量,除非使用强制类型转换。下面来看一段示例代码,根据string类型,定义一种新的类型,新类型名称是name:

type name string

为什么要使用类型定义呢?

类型定义可以在原类型的基础上创造出新的类型,有些场合下可以使代码更加简洁,如下边示例代码:

package main
import (
  "fmt"
)
// 定义一个接收一个字符串类型参数的函数类型
type handle func(str string)
// exec函数,接收handle类型的参数
func exec(f handle) {
  f("hello")
}
func main() {
  // 定义一个函数类型变量,这个函数接收一个字符串类型的参数
  var p = func(str string) {
    fmt.Println("first", str)
  }
  exec(p)
  // 匿名函数作为参数直接传递给exec函数
  exec(func(str string) {
    fmt.Println("second", str)
  })
}

输出信息是:

first hello
second hello

上边的示例是类型定义的一种简单应用场合,如果不使用类型定义,那么想要实现上边示例中的功能,应该怎么书写这段代码呢?

// exec函数,接收handle类型的参数
func exec(f func(str string)) {
  f("hello")
}

exec函数中的参数类型,需要替换成func(str string)了,咋一看去也不复杂,但是假如exec接收一个需要5个参数的函数变量呢?是不是感觉参数列表就会很长了。

func exec(f func(str string, str2 string, num int, money float64, flag bool)) {
  f("hello")
}

从上边的代码可以发现,exec函数的参数列表可读性变差了。下边再来看看使用类型定义是怎么实现这个功能:

package main
import (
  "fmt"
)
// 定义一个需要五个参数的函数类型
type handle func(str string, str2 string, num int, money float64, flag bool)
// exec函数,接收handle类型的参数
func exec(f handle) {
  f("hello", "world", 10, 11.23, true)
}
func demo(str string, str2 string, num int, money float64, flag bool) {
  fmt.Println(str, str2, num, money, flag)
}
func main() {
  exec(demo)
}

类型别名

类型别名这个特性在golang1.9中引入。使用类型别名定义出来的类型与原类型一样,即可以与原类型变量互相赋值,又拥有了原类型的所有方法集。给strng类型取一个别名,别名名称是name:

type name = string

类型别名与类型定义不同之处在于,使用类型别名需要在别名和原类型之间加上赋值符号(=);使用类型别名定义的类型与原类型等价,而使用类型定义出来的类型是一种新的类型。

如下边示例:

package main
import (
  "fmt"
)
type a = string
type b string
func SayA(str a) {
  fmt.Println(str)
}
func SayB(str b) {
  fmt.Println(str)
}
func main() {
  var str = "test"
  SayA(str)
  
  //错误参数传递,str是字符串类型,不能赋值给b类型变量
  SayB(str)
}

这段代码在编译时会出现如下错误:

.\main.go:21:6: cannot use str (type string) as type b in argument to SayB

从错误信息可知,str为字符串类型,不能当做b类型参数传入SayB函数中。而str却可以当做a类型参数传入到SayA函数中。由此可见,使用类型别名定义的类型与原类型一致,而类型定义定义出来的类型,是一种新的类型。

给类型别名新增方法,会添加到原类型方法集中

给类型别名新增方法后,原类型也能使用这个方法。下边请看一段示例代码:

package main
import (
  "fmt"
)
// 根据string类型,定义类型S
type S string
func (r *S) Hi() {
  fmt.Println("S hi")
}
// 定义S的类型别名为T
type T = S
func (r *T) Hello() {
  fmt.Println("T hello")
}
// 函数参数接收S类型的指针变量
func exec(obj *S) {
  obj.Hello()
  obj.Hi()
}
func main() {
  t := new(T)
  s := new(S)
  exec(s)
  // 将T类型指针变量传递给S类型指针变量
  exec(t)
}

输出信息是:

T hello
S hi
T hello
S hi

上边的示例中,S是原类型,T是S类型别名。在给T增加了Hello方法后,S类型的变量也可以使用Hello方法。说明给类型别名新增方法后,原类型也能使用这个方法。从示例中可知,变量t可以赋值给S类型变量s,所以类型别名是给原类型取了一个小名,本质上没有发生任何变化。

类型别名,只能对同一个包中的自定义类型产生作用。举个例子,golang sdk中有很多个包,是不是我们可以使用类型别名,给sdk包中的结构体类型新增方法呢?答案是:不行。请牢记一点:类型别名,只能对包内的类型产生作用,对包外的类型采用类型别名,在编译时将会提示如下信息:

cannot define new methods on non-local type string

类型查询

类型查询,就是根据变量,查询这个变量的类型。为什么会有这样的需求呢?goalng中有一个特殊的类型interface{},这个类型可以被任何类型的变量赋值,如果想要知道到底是哪个类型的变量赋值给了interface{}类型变量,就需要使用类型查询来解决这个需求,示例代码如下:

package main
import (
  "fmt"
)
func main() {
    // 定义一个interface{}类型变量,并使用string类型值”abc“初始化
    var a interface{} = "abc"
    
    // 在switch中使用 变量名.(type) 查询变量是由哪个类型数据赋值。
    switch v := a.(type) {
    case string:
      fmt.Println("字符串")
    case int:
        fmt.Println("整型")
    default:
      fmt.Println("其他类型", v)
    }
}

如果使用.(type)查询类型的变量不是interface{}类型,则在编译时会报如下错误:

cannot type switch on non-interface value a (type string)

如果在switch以外地方使用.(type),则在编译时会提示如下错误:

use of .(type) outside type switch

所以,使用type进行类型查询时,只能在switch中使用,且使用类型查询的变量类型必须是interface{}

看完上述内容,你们对go语言中的type有进一步的了解吗?如果还想了解更多相关内容,欢迎关注北单博客行业资讯频道,感谢各位的阅读。

原创文章,作者:HANRW,如若转载,请注明出处:https://www.beidanyezhu.com/a/26446.html

(0)
HANRW的头像HANRW
上一篇 2025-01-03
下一篇 2025-01-03

相关推荐

  • go语言可以用哪些框架

    go语言使用的框架有:1、Beego框架;2、Buffalo框架;3、Echo框架;4、Gin框架;5、Iris框架;6、Revel框架。 6款好用的go语言web框架: Beeg…

  • go语言怎么引入包

    go语言引入包的方法:可以直接使用【import "包名"】来引入一个包。如果需要同时引入多个包,可以使用【import {"包名" &qu…

    2025-01-07
  • go语言有什么开发工具

    go语言开发工具有:1、GoLand;2、LiteIDE;3、Eclipse。LiteIDE是一款开源、跨平台的轻量级Go语言集成开发环境。 开发工具介绍: 1、GoLand Go…

    2025-01-07
  • vscode如何配置go语言开发环境

    Golang 环境配置 1) 首先下载适合你系统的安装包 2)下载完成安装到指定目录即可。我这里是(D:\Go)。 3)配置Glang环境变量 进入我的电脑->高级设置-&g…

    2025-01-07
  • go语言defer怎么用

    go语言defer的用法:1、defer语句在函数返回之前或函数中的return语句之后执行;2、多个defer语句的执行顺序是逆序执行;3、在panic语句后的defer语句不执…

  • windows下如何搭建go语言开发环境

    windows下搭建go语言开发环境的方法:1、在官网下载go语言开发包;2、安装go语言开发包;3、设置GOPATH环境变量;4、测试go开发包是否安装成功。 具体步骤如下: 一…

    2025-01-07
  • go语言的7大优势是什么

    go语言的优势有:1、学习曲线容易;2、开发效率和运行效率高;3、自由高效;4、拥有强大的标准库;5、部署方便;6、高度支持并发性;7、稳定性高。 go语言的优势: 1、学习曲线容…

  • go语言指的是什么

    go语言是一种静态强类型、编译型语言,它的语法与C语言相近。go语言规定每行程序结束后不需要撰写分号,大括号不能够换行放置,if判断式和for循环不需要以小括号包裹。 详细介绍: …

  • go语言适合于什么领域

    go语言适用的领域有:1、服务器编程;2、分布式系统;3、网络编程;4、内存数据库;5、云平台;6、游戏服务端的开发。go语言是一种静态强类型、编译型语言。 Go(又称 Golan…

  • yum如何安装go语言

    yum安装go语言的方法:首先执行【yum -y install golang】命令安装go;然后编辑profile文件,配置环境变量;最后执行【source /etc/profi…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

分享本页
返回顶部