经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Go语言 » 查看文章
Golang通脉之类型定义
来源:jb51  时间:2021/10/25 17:06:59  对本文有异议

1、自定义类型

在Go语言中有一些基本的数据类型,如 string 、 整型 、 浮点型 、 布尔 等数据类型, Go语言中可以使用 type 关键字来定义自定义类型。

type是Go语法里的重要而且常用的关键字,type绝不只是对应于C/C++中的typedef。搞清楚type的使用,就容易理解go语言中的核心概念structinterface、函数等的使用。

2、类型定义

2.1 定义结构体

使用 type 可以定义结构体类型:

  1. //1、定义结构体
  2. //结构体定义
  3. type person struct {
  4. name string //注意后面不能有逗号
  5. age int
  6. }
  7.  

2.2 定义接口

使用 type 可以定义接口类型:

  1. type USB interface {
  2. start()
  3. end()
  4. }
  5.  

2.3 定义其他的新类型

使用 type ,还可以定义新类型。

语法:

type 类型名 Type

示例代码:

  1. type myint int
  2. type mystr string
  3.  
  4. func main() {
  5.  
  6. var i1 myint
  7. var i2 = 100
  8. i1 = 100
  9. fmt.Println(i1)
  10. //i1 = i2 //cannot use i2 (type int) as type myint in assignment
  11. fmt.Println(i1,i2)
  12. var name mystr
  13. name = "王二狗"
  14. var s1 string
  15. s1 = "李小花"
  16. fmt.Println(name)
  17. fmt.Println(s1)
  18. name = s1 //cannot use s1 (type string) as type mystr in assignment
  19. }
  20.  

2.4 定义函数的类型

Go语言支持函数式编程,可以使用高阶编程语法。一个函数可以作为另一个函数的参数,也可以作为另一个函数的返回值,那么在定义这个高阶函数的时候,如果函数的类型比较复杂,可以使用type来定义这个函数的类型:

  1. func main() {
  2. res1 := fun1()
  3. fmt.Println(res1(10,20))
  4. }
  5.  
  6.  
  7. type my_fun func (int,int)(string)
  8.  
  9. //fun1()函数的返回值是my_func类型
  10. func fun1 () my_fun{
  11. fun := func(a,b int) string {
  12. s := strconv.Itoa(a) + strconv.Itoa(b)
  13. return s
  14. }
  15. return fun
  16. }
  17.  

3、类型别名

类型别名规定TypeAlias只是Type的别名,本质上TypeAliasType是同一个类型。就像一个孩子小时候有小名、乳名,上学后用学名,英语老师又会给他起英文名,但这些名字都指的是他本人。

类型别名是 Go 1.9 版本添加的新功能。主要用于代码升级、迁移中类型的兼容性问题。在 C/C++语言中,代码重构升级可以使用宏快速定义新的一段代码。Go 语言中没有选择加入宏,而是将解决重构中最麻烦的类型名变更问题。

type TypeAlias = Type

在 Go 1.9 版本之前的内建类型定义的代码是这样写的:

  1. type byte uint8
  2. type rune int32
  3.  
  4.  

而在 Go 1.9 版本之后变为:

  1. type byte = uint8
  2. type rune = int32
  3.  
  4.  

这个修改就是配合类型别名而进行的修改。

4、类型定义和类型别名的区别

类型别名与类型定义表面上看只有一个等号的差异,我们通过下面的这段代码来理解它们之间的区别。

  1. //类型定义
  2. type NewInt int
  3.  
  4. //类型别名
  5. type MyInt = int
  6.  
  7. func main() {
  8. var a NewInt
  9. var b MyInt
  10. fmt.Printf("type of a:%T\n", a) //type of a:main.NewInt
  11. fmt.Printf("type of b:%T\n", b) //type of b:int
  12. }
  13.  

结果显示a的类型是 main.NewInt ,表示main包下定义的 NewInt 类型。b的类型是 int MyInt 类型只会在代码中存在,编译完成时并不会有 MyInt 类型。

5、非本地类型不能定义方法

能够随意地为各种类型起名字,是否意味着可以在自己包里为这些类型任意添加方法?

  1. // 定义time.Duration的别名为MyDuration
  2. type MyDuration = time.Duration
  3. // 为MyDuration添加一个函数
  4. func (m MyDuration) EasySet(a string) { //cannot define new methods on non-local type time.Duration
  5. }
  6. func main() {
  7. }
  8.  

以上代码报错。报错信息:cannot define new methods on non-local type time.Duration

编译器提示:不能在一个非本地的类型 time.Duration 上定义新方法。非本地方法指的就是使用 time.Duration 的代码所在的包,也就是 main 包。因为 time.Duration 是在 time 包中定义的,在 main 包中使用。time.Duration 包与 main 包不在同一个包中,因此不能为不在一个包中的类型定义方法。

解决这个问题有下面两种方法:

  • 将类型别名改为类型定义: type MyDuration time.Duration ,也就是将 MyDuration 从别名改为类型。
  • MyDuration 的别名定义放在 time 包中。

6、在结构体成员嵌入时使用别名

当类型别名作为结构体嵌入的成员时会发生什么情况?

  1. type Person struct {
  2. name string
  3. }
  4.  
  5. func (p Person) Show() {
  6. fmt.Println("Person-->",p.name)
  7. }
  8.  
  9. //类型别名
  10. type People = Person
  11.  
  12. type Student struct {
  13. // 嵌入两个结构
  14. Person
  15. People
  16. }
  17.  
  18. func (p People) Show2(){
  19. fmt.Println("People------>",p.name)
  20. }
  21.  
  22. func main() {
  23. //
  24. var s Student
  25.  
  26. //s.name = "王二狗" //ambiguous selector s.name
  27. s.People.name = "李小花"
  28. s.Person.name = "王二狗"
  29. //s.Show() //ambiguous selector s.Show
  30. s.Person.Show()
  31. s.People.Show2()
  32. fmt.Printf("%T,%T\n",s.Person,s.People) //main.Person,main.Person
  33.  
  34. }
  35.  

在通过s直接访问name的时候,或者s直接调用Show()方法,因为两个类型都有 name字段和Show() 方法,会发生歧义,证明People 的本质确实是Person 类型。

到此这篇关于Golang通脉之类型定义的文章就介绍到这了,更多相关Golang 类型定义内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号