【Golang】Go语言中type关键字到底是什么?

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,Golang开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:Go语言开发零基础到高阶实战
景天的主页:景天科技苑

在这里插入图片描述

文章目录

  • Go语言中Type的详细用法教程
    • 1. type使用语法
      • 1、定义新类型
      • 2、给存在的类型起别名
      • 进阶用法
        • 示例:类型别名与结构体
    • 2. 结构体类型(Struct Types)
      • 定义与基本用法
        • 语法
        • 示例
      • 结构体字段的访问与修改
      • 结构体标签(Struct Tags)
      • 匿名结构体与内嵌结构体
        • 匿名结构体
        • 内嵌结构体
    • 3. 接口类型(Interface Types)
      • 定义与基本用法
        • 语法
        • 示例
      • 接口与多态
        • 示例:使用接口实现多态
    • 4. 函数类型(Function Types)
      • 定义与基本用法
        • 语法
        • 示例
    • 5. 指针类型(Pointer Types)
        • 示例
    • 6. 类型断言(Type Assertions)
        • 语法
        • 示例
    • 7. 类型选择(Type Switches)
        • 语法
        • 示例
    • 8. 自定义类型的方法
        • 示例
    • 9. 类型系统的高级特性
      • 空接口
      • 隐式接口
      • 类型的零值
    • 10. 总结

Go语言中Type的详细用法教程

在Go语言中,type关键字是构建自定义数据类型和声明新类型的基础。通过type,我们可以定义类型别名、结构体、接口、函数类型等多种数据类型,这些自定义类型极大地增强了Go语言的灵活性和表达能力。本文将结合实际案例,详细探讨type在Go语言中的多种用法。

1. type使用语法

1、定义新类型

type NewTypeName OldTypeName
其中,NewTypeName是新创建的类型别名,OldTypeName是已存在的类型。

2、给存在的类型起别名

type xxx = 类型 ,将某个类型赋值给 xxx,相当于这个类型的别名。程序原酸的时候还是按原类型来处理

type关键字的理解:
1、type 定义一个类型

  • type User struct 定义结构体类型
  • type User interface 定义接口类型
  • type Diy (int、string、…) 自定义类型,全新的类型

2、type 起别名

  • type xxx = 类型 ,将某个类型赋值给 xxx,相当于这个类型的别名
  • 别名只能在写代码的时候使用,增加代码的可阅读性。
  • 真实在项目的编译过程中,它还是原来的类型。

总结:

  • type xxx TTT 自定义类型
  • type xxx = TTT 起别名

代码示例:

package mainimport "fmt"// var 变量   type 类型(结构体、接口、别名...)// type的别名用法,全局变量中
// 这是定义了一个新类型 MyInt,是int转换过来的,和int一样,但是不能通int发生操作,类型不同
// 这里他俩MyInt int 是两个类型
// 创建了一种新类型!type MyInt intfunc main() {var a MyInt = 20 // MyIntvar b int = 10   // int//自定义的类型和原类型也不能做运算// invalid operation: a + b (mismatched types MyInt and int)//fmt.Println(a + b)//可以进行强制类型转换// 类型转换: T(v)fmt.Println(int(a) + b) // 30//查看他俩数据类型fmt.Printf("%T\n", a) // main.MyIntfmt.Printf("%T\n", b) // int// 给int起一个小名,但是它还得是int   type  anytype diyint = int //用等号赋值,这里diyint和int是一样的var c diyint = 30//查看数据类型,可以看到还是原来的数据类型fmt.Printf("%T\n", c) // int//此时的c和基本int类型的数据可以直接进行运算fmt.Println(c + b) //40}/*
type关键字的理解:
1、type 定义一个类型- type User struct 定义结构体类型- type User interface 定义接口类型- type Diy (int、string、....) 自定义类型,全新的类型2、type 起别名- type xxx = 类型 ,将某个类型赋值给 xxx,相当于这个类型的别名- 别名只能在写代码的时候使用,增加代码的可阅读性。- 真实在项目的编译过程中,它还是原来的类型。
*/

在这里插入图片描述

进阶用法

类型别名不仅限于基础类型,也可以用于复合类型,如结构体、切片、映射等。然而,重要的是要理解,类型别名和原始类型在类型系统中是被视为等价的。

示例:类型别名与结构体
type Point struct {X, Y int
}type Coord Pointfunc main() {var p Point = Point{1, 2}var c Coord = Coord{3, 4}// Point 和 Coord 是等价的var q Point = c // 正确,因为 Point 和 Coord 是等价的fmt.Println(q)  // 输出: {3 4}
}

尽管PointCoord在代码中是两个不同的类型名称,但在Go的类型系统中,它们被视为等价。因此,Point类型的变量可以赋值为Coord类型的值,反之亦然。

2. 结构体类型(Struct Types)

定义与基本用法

结构体是Go语言中的一种复合数据类型,用于将多个不同类型的变量组合成一个单一的类型。结构体类型允许我们创建具有多个属性的自定义类型。

语法
type StructName struct {Field1 FieldType1Field2 FieldType2// ...
}
示例
package mainimport "fmt"type Person struct {Name stringAge  int
}func main() {p := Person{Name: "Alice", Age: 30}fmt.Println(p)  // 输出: {Alice 30}
}

在上述代码中,我们定义了一个Person结构体,它有两个字段:NameAge。然后,我们创建了一个Person类型的变量p,并初始化了它的字段。

结构体字段的访问与修改

结构体字段可以通过点操作符.来访问和修改。

p.Name = "Bob"
fmt.Println(p.Name)  // 输出: Bob

结构体标签(Struct Tags)

结构体字段还可以包含标签(也称为元数据),这些标签用于为字段提供额外的信息,常用于JSON序列化/反序列化等场景。

type Person struct {Name string `json:"name"`Age  int    `json:"age"`
}

匿名结构体与内嵌结构体

Go还允许定义匿名结构体和将结构体作为另一个结构体的字段(内嵌结构体)。

匿名结构体
var person = struct {Name stringAge  int
}{"Alice", 30}
fmt.Println(person)  // 输出: {Alice 30}
内嵌结构体
type Address struct {City, State string
}type Person struct {Name stringAge  intAddress
}func main() {p := Person{Name: "Alice",Age:  30,Address: Address{City:  "New York",State: "NY",},}fmt.Println(p)  // 输出: {Alice 30 {New York NY}}fmt.Println(p.City)  // 输出: New York
}

在上述代码中,Address结构体被内嵌到Person结构体中。这允许我们直接通过Person类型的实例访问Address结构体的字段。

3. 接口类型(Interface Types)

定义与基本用法

接口是一种抽象类型,它定义了一组方法,但不实现它们。接口由一组方法签名组成,这些方法的具体实现由其他类型(如结构体)提供。

语法
type InterfaceName interface {Method1(param1 ParamType1) ReturnType1Method2(param1 ParamType2, param2 ParamType2) ReturnType2// ...
}
示例
package mainimport "fmt"type Shape interface {Area() float64
}type Circle struct {Radius float64
}func (c Circle) Area() float64 {return math.Pi * c.Radius * c.Radius
}func main() {var s Shape = Circle{Radius: 5}fmt.Println(s.Area())  // 输出: 78.53981633974483
}

在上述代码中,我们定义了一个Shape接口和一个Circle结构体。Circle结构体实现了Shape接口中的Area方法。然后,我们将Circle的实例赋值给Shape接口类型的变量s,并调用了Area方法。

接口与多态

接口是实现多态性的关键。通过接口,我们可以编写不依赖于具体实现的代码,从而使代码更加灵活和可重用。

示例:使用接口实现多态
package mainimport "fmt"type Shape interface {Area() float64
}type Circle struct {Radius float64
}func (c Circle) Area() float64 {return math.Pi * c.Radius * c.Radius
}type Rectangle struct {Width, Height float64
}func (r Rectangle) Area() float64 {return r.Width * r.Height
}func printArea(s Shape) {fmt.Println(s.Area())
}func main() {circle := Circle{Radius: 5}rectangle := Rectangle{Width: 4, Height: 6}printArea(circle)  // 输出: 78.53981633974483printArea(rectangle)  // 输出: 24
}

在上述代码中,我们定义了一个printArea函数,它接受一个Shape接口类型的参数。这意味着它可以接受任何实现了Shape接口的类型的实例作为参数。这样,我们就实现了多态性。

4. 函数类型(Function Types)

定义与基本用法

在Go中,我们还可以定义函数类型,即函数的签名。函数类型允许我们将函数作为参数传递给其他函数,或者将函数作为返回值。

语法
type FunctionName func(param1 ParamType1, param2 ParamType2) ReturnType
示例
package mainimport "fmt"type AddFunc func(a, b int) intfunc add(a, b int) int {return a + b
}func apply(f AddFunc, x, y int) int {return f(x, y)
}func main() {result := apply(add, 5, 3)fmt.Println(result)  // 输出: 8
}

在上述代码中,我们定义了一个AddFunc函数类型,它接受两个int类型的参数并返回一个int类型的结果。然后,我们定义了一个add函数,它符合AddFunc的签名。最后,我们定义了一个apply函数,它接受一个AddFunc类型的参数和两个int类型的参数,并返回调用该函数的结果。

在Go语言中,type 关键字不仅用于定义基础的数据类型别名、结构体、接口和函数类型,还有一些高级用法和特性。接下来,我们将继续探讨 type 在Go语言中的其他用法。

5. 指针类型(Pointer Types)

虽然指针类型本身不是通过 type 关键字直接定义的(因为所有类型都可以有指针),但理解指针类型对于深入掌握Go语言至关重要。在Go中,指针类型允许我们直接访问变量的内存地址,并通过指针来修改变量的值。

示例
package mainimport "fmt"func main() {x := 10p := &x  // p 是一个指向 x 的指针fmt.Println(*p)  // 输出: 10*p = 20  // 通过指针修改 x 的值fmt.Println(x)   // 输出: 20
}

在上面的代码中,&x 获取了变量 x 的内存地址,并将其赋值给指针变量 p*p 是对指针 p 进行解引用,即获取指针所指向的值。

6. 类型断言(Type Assertions)

类型断言提供了一种访问接口值底层具体值的方式。类型断言主要用于将接口类型的变量转换为具体的类型。

语法
value, ok := x.(T)

如果 x 不是 T 类型,则 ok 会是 false,且 value 会是 T 类型的零值。如果 xT 类型,则 ok 会是 true,且 value 会是 x 的值。

示例
package mainimport "fmt"func main() {var i interface{} = "hello"s, ok := i.(string)if ok {fmt.Println(s)  // 输出: hello} else {fmt.Println("类型断言失败")}// 尝试将i断言为int类型,会失败n, ok := i.(int)if !ok {fmt.Println("类型断言失败")}
}

7. 类型选择(Type Switches)

类型选择是 switch 语句的一个变种,用于在多个类型之间进行选择。它通常与接口一起使用,以检查接口值持有的具体类型。

语法
switch v := x.(type) {
case T1:// 处理 T1 类型的 v
case T2:// 处理 T2 类型的 v
// ...
default:// 处理所有其他类型
}
示例
package mainimport "fmt"func do(i interface{}) {switch v := i.(type) {case int:fmt.Printf("整型: %v\n", v)case string:fmt.Printf("字符串型: %q\n", v)default:fmt.Printf("未知类型\n")}
}func main() {do(21)do("hello")do(true)
}

8. 自定义类型的方法

在Go中,你可以为任何自定义类型(结构体、类型别名等)定义方法。方法是附加到类型上的函数,其第一个参数是接收者(receiver),接收者指定了方法所属的类型。

示例
package mainimport "fmt"type MyInt int// 为 MyInt 类型定义方法
func (m MyInt) SayHello() {fmt.Println("Hello from MyInt:", m)
}func main() {var x MyInt = 10x.SayHello()  // 输出: Hello from MyInt: 10
}

9. 类型系统的高级特性

Go的类型系统还包含一些高级特性,如空接口(interface{})、隐式接口、类型嵌入(在结构体中使用)和接口的组合等。这些特性为Go提供了强大的灵活性和表达力。

空接口

空接口 interface{} 没有定义任何方法,因此任何类型都实现了空接口。空接口通常用于需要存储任意类型值的场景,如标准库中的 fmt.Println 函数和 json.Marshal 函数。

隐式接口

Go的接口是隐式的,意味着我们不需要显式声明一个类型实现了某个接口。只要类型实现了接口中定义的所有方法,那么它就自动实现了该接口。

类型的零值

Go中的每个类型都有一个零值。对于数值类型,零值是0;对于布尔类型,零值是false;对于字符串,零值是空字符串"";对于指针、切片、映射、通道(channel)、函数和接口,零值是nil。了解类型的零值对于编写健壮的Go代码至关重要。

10. 总结

Go语言中的 type 关键字是构建自定义数据类型和声明新类型的基础。通过类型别名、结构体、接口、函数类型等,Go提供了丰富的类型系统,使得我们可以编写出既灵活又强大的代码。掌握 type 的用法,是深入理解Go语言的关键。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1546925.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

FMEA实战指南:精准定参,筑牢产品质量防线

在FMEA分析中,严重度、频度和探测度三个参数的确定直接关系到风险顺序数(RPN)的计算,进而影响产品故障模式的优先排序和改进措施的制定。因此,掌握如何精准确定这些参数,对于提高产品质量、降低风险具有重要意义。深圳天行健企业管…

水面巡检船垃圾漂浮物检测系统源码分享

水面巡检船垃圾漂浮物检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of …

​初学者的自动化测试路线图:Playwright和TypeScript

测试对于确保软件运行良好非常重要。测试自动化通过使用特殊的工具和程序快速准确地进行测试使这变得更容易。这有助于检查软件是否完成了它应该做的事情、它的性能如何以及它是否可靠。 通过自动化重复测试任务,团队可以显着加快测试过程,扩大测试覆盖…

泛微OA提示信息换行

⭐️如果对你有用的话,希望可以点点赞,感谢了⭐️ WfForm.setTextFieldEmptyShowContent("field111", "格式模板:将顾客客诉原因文字描述清楚\n如:顾客因对美养师手法不满,觉得力度不够,没…

架构师:消息队列的技术指南

1、简述 消息队列(Message Queue, MQ)是一种异步通信机制,允许系统的各个组件通过消息在彼此之间进行通信。消息队列通过解耦系统组件、缓冲高峰期请求和提高系统的可扩展性,成为分布式系统中不可或缺的一部分。 2、工作原理 消息队列的基本工作原理是生产者将消息发布到…

远程办公生产力软件推荐,每天比同事早下班3个小时的秘密!

每天比同事早下班3个小时的秘密,终于被我找到啦! 网易GameViewer远程是一款高效便捷的远程办公工具,支持多点触控、虚拟鼠标键盘、4K画质和低延迟。其隐私屏功能保护文件安全。 只需三步:安装、登录、远控,即可轻松提升…

Docker-2.如何保存数据退出

在使用Docker时,我们常常需要修改容器中的文件,并且希望在容器重启后这些修改能够得到保留。 0.简介 使用Docker时有一个需要注意的问题:当你修改了容器中的文件后,重启容器后这些修改将会被重置,深入研究这个问题。 …

远程访问软路由

远程访问软路由主要涉及通过互联网从远程位置访问和控制基于软件的路由器系统。以下是远程访问软路由的一般方法: 一、远程访问软路由的方法 通过Web管理界面访问: 适用于大多数支持Web管理的软路由系统。用户只需在浏览器中输入软路由的公网IP地址或域…

react中的ref三种形式

1&#xff0c;字符串形式 <!-- 创建盒子 --><div id"test"></div> <script type"text/babel">class Demo extends React.Component{render(){return(<div><input type"text" refinput1 /><button onCl…

从销售到 AI 算法工程师 | 转行人工智能大模型(含面经裁员幸存指南)

我叫王东&#xff0c;90后&#xff0c;和大家分享一下我的人工智能转型之路。 农学毕业&#xff0c;投身互联网做销售 机遇难求&#xff0c;养殖梦碎 我是土生土长的农村人&#xff0c;小时候经常和小鱼小虾打交道&#xff0c;上大学的时候就选择了农学专业&#xff0c;想着…

OpenKylin--解压文件

tar zxf dotnet-sdk-6.0.425-linux-x64.tar.gzrootsanzk-pc:/home/dotnet# tar zxf dotnet-sdk-6.0.425-linux-x64.tar.gz参考&#xff1a; rootxxx-pc:/home/xxx# mkdir -p /home/dotnet && tar zxf dotnet-sdk-6.0.411-linux-x64.tar.gz -C /home/dotnet mkdir -p /…

STM32F1+HAL库+FreeTOTS学习13——二值信号量

STM32F1HAL库FreeTOTS学习13——二值信号量 1. 信号量2. 二值信号量3. 相关API函数3.1 创建二值信号量3.2 获取信号量3.3 释放信号量3.4 删除信号量 4. 二值信号量操作实验1. 实验内容2. 代码实现&#xff1a;3. 运行结果 上一期我们学习了FreeRTOS中的队列&#xff0c;这一期我…

【含文档】基于Springboot+Vue的高校失物招领平台(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

Excel中用位置筛选解法

有 2022 年 1 月的日销售额统计表如下所示&#xff1a; 筛选出偶数日的销售额&#xff1a; spl("E(?1).select(#%20)",A1:B32)#表示当前行号 免费课程、软件免费下载

免杀笔记 ---> 无痕Hook?硬件断点 Syscall!

说到Hook&#xff0c;我们有很多Hook&#xff0c;像Inline-Hook&#xff0c;我们也是用的比较多&#xff0c;但是正如我上一篇Blog说的&#xff0c;他会对内存进行修改&#xff0c;如果EDR或者AV增加一个校验机制&#xff0c;不断检验某一块内存&#xff0c;那么就算你用syscal…

SQL 性能调优

什么是 SQL 性能调优 SQL 性能调优是优化 SQL 查询以尽可能高效地运行的过程&#xff0c;从而减少数据库负载并提高整体系统性能。这是通过各种技术实现的&#xff0c;例如分析查询执行计划、优化索引和重写查询以确保最佳执行路径。目标是最大限度地减少执行查询所需的时间和…

【已解决】【Hadoop】【./bin的使用】bash: ./bin/hdfs: 没有那个文件或目录

在 Hadoop 环境中&#xff0c;决定何时在命令前添加 ./bin 和如何处理路径 /home/hadoop 与 /usr/local/hadoop 的问题&#xff0c;主要取决于你的当前工作目录和环境变量的设置。以下是一些指导原则&#xff1a; 何时使用 ./bin&#xff1a; 当前目录是 Hadoop 安装目录&…

高通AI应用程序开发1:SNPE 概述

1. 功能 The Qualcomm Neural Processing SDK&#xff08;SNPE&#xff09; 是 Qualcomm Snapdragon 软件加速运行时&#xff0c;用于执行深度神经网络。使用 SNPE&#xff0c;用户可以: 执行任意深度的神经网络 在 Snapdragon CPU、Adreno GPU 或 Hexagon DSP 上执行网络。 …

hadoop大数据平台操作笔记(下)

–接hive数据库的操作 函数的操作 聚合函数 函数名说明sun()求和max()最大值min()最小值count()统计avg()平均值 单行函数 数字类型 函数名说明abs()绝对值ceil()进一取整floor()去尾取整round()四舍五入pow()幂运算rand()随机值&#xff0c;获取0~1的小数percentile(字段…

卷轴模式:一种新型的电子商务营销策略

随着电子商务行业的蓬勃发展&#xff0c;各类创新营销策略层出不穷&#xff0c;旨在吸引更多消费者并提升销售额。在这之中&#xff0c;卷轴模式以其独特的优势和可观的收益逐渐受到业界renxb001的关注。本文将深入探讨卷轴模式的概念、优势、应用场景以及如何参与其中。 卷轴…