Go 类型系统

1、命名类型和未命名类型

命名类型:类型可以通过标识符来表示,这种类型称为命名类型。Go语言的基本类型中有20个预声明简单类型都是命名类型,Go语言还有一种命名类型——用户自定义类型。

未命名类型:一个类型由预声明类型、关键字和操作符组合而成,这个类型称为未命名类型。未命名类型又称为类型字面量(Type Literal),本书中的未命名类型和类型字面量二者等价。

Go语言的基本类型中的复合类型:数组(array)、切片(slice)、字典(map)、通道(channel)、指针(pointer)、函数字面量(function)、结构(struct)和接口(interface)都属于类型字面量,也都是未命名类型。所以,*int、[]int、 [2]int、map[k]v都是未命名类型。

注意:前面所说的结构和接口是未命名类型,这里的结构和接口没有使用type格式定义。

// 使用type声明的是命名类型
type Person struct {name stringage  int
}func main() {// 使用struct字面量声明的是未命名类型a := struct {name stringage  int}{"Tom", 18}fmt.Printf("%T\n", a) // struct { name string; age int }fmt.Printf("%v\n", a) // {Tom 18}b := Person{"Jerry", 20}fmt.Printf("%T\n", b) // main.Personfmt.Printf("%v\n", b) // {Jerry 20}
}

命名类型和未命名类型说明如下:

  • 未命名类型和类型字面量是等价的,通常所说的Go语言基本类型中的复合类型就是类型字面量,所以,未命名类型、类型字面量和Go语言基本类型中的复合类型三者等价。
  • 通常所说的Go语言基本类型中的简单类型就是预声明类型,它们都属于命名类型。
  • 预声明类型是命名类型的一种,另一类命名类型是自定义类型。
2、自定义类型

Go语言允许用户定义类型。当用户声明一个新类型时,这个声明就给编译器提供了一个框架,告知必要的内存大小和表示信息。声明后的类型与内置类型的运作方式类似。Go语言中声明用户定义的类型有两种方法,最常用的方法是使用关键字struct,它可以让用户创建一个结构类型。

结构类型通过组合一系列固定且唯一的字段来声明,如下面代码所示。结构中每个字段都会用一个已知类型声明,这个已知类型可以是内置类型,也可以是其他用户定义的类型。

//user在程序里定义一个用户类型
type user struct {name string   emai1 string   ext int   privileged bool
}//声明user类型的变量,并初始化所有字段
func main() {tom := user{name:       "Tom",email:      "Tom@163.com",ext:        123,privileged: false,}fmt.Println(tom)
}// 第二种形式没有字段名,只声明对应的值,结尾不需要逗号。
// 在这种形式下,值的顺序很重要,必须和结构声明中字段的顺序一致。
lisa := user{"Lisa", "Lisa@example.com ", 123, true}
  • 结构类型的声明,这个声明以关键字type开始,之后是新类型的名字,最后是关键字struct。
  • 这个结构类型有4个字段,每个字段都基于一个内置类型。一旦声明了类型就可以使用这个类型创建值。
type user struct {name       stringemail      stringext        intprivileged bool
}type admin struct {person userlevel  string
}func main() {fred := admin{person: user{name:       "Tom",email:      "Tom@163.com",ext:        123,privileged: false,},level: "super",}fmt.Println(fred) // {{Tom Tom@163.com 123 false} super}
}

另一种声明用户定义类型的方法是,基于一个已有的类型,将其作为新类型的类型说明。标准库使用这种声明类型的方法,从内置类型创建出很多更加明确的类型,并赋予更高级的功能:

type Duration int64

上述代码是标准库的time包中的一个类型声明。Duration是一种描述时间隔的类型,单位是纳秒(ns)。这个类型使用内置的int64类型作为其表示,在Duration类型的声明中,将int64类型称为Duration的基础类型。不过,虽然int64是基础类型,但Go语言并不认为Duration和int64是同一种类型,这两个类型是完全不同的、有区别的类型。

类型int64的值不能作为类型Duration的值来用。虽然int64类型是基础类型,Duration类型依然是一个独立的类型。两种不同类型的值即便互相兼容,也不能互相赋值,编译器不会对不同类型的值进行隐式转换。

3、类型的强制转换

描述:由于Go语言是强类型的语言,如果不满足自动转换的条件,则必须进行强制类型转换。

语法:var a T=(T) (b)

非常量类型的变量x可以强制转化并传递给类型T,满足以下任一条件即可:

  • x可以直接赋值给T类型变量。
  • x的类型和T具有相同的底层类型。
  • x的类型和T都是未命名的指针关型,并且指针指向的类型具有相同的成员类型。
  • x的类型和T都是整型,或者都是浮点型。
  • x的类型和T都是复数类型。
  • x是整数值或[]byte类型的值,T是string类型。
  • x是一个字符串,T是[]byte或[]rune。
type Map map[string]string
type iMap Mapfunc (m Map) print() {for _, key := range m {fmt.Println(key)}
}// 只要底层类型是slice、map等支持range的类型字面量,新类型仍然可以使用range迭代
func (m iMap) print() {for _, key := range m {fmt.Println(key)}
}func main() {mp := make(map[string]string, 10)mp["hi"] = "tata"// mp 与 ma 有相同的底层类型map [string]string, 并且mp是未命名类型var ma Map = mp// im 与 ma 虽然有相同的底层类型,但是二者中没有一个是字面量类型,不能直接赋值,可以强制进行类型转换// var im iMap = mavar im iMap = (iMap)(ma)ma.print() // tataim.print() // tata
}

字符串和字节切片之间的转换最常见:

func main() {s := "hello,world!"var a []bytea = []byte(s)var b stringb = string(a)var c []runec = []rune(s)fmt.Printf("%T\n", a) // []uint8 type是int8的别名fmt.Printf("%T\n", b) // stringfmt.Printf("%T\n", c) // []int32 rune是int32的别名
}

在使用类型的强制转换时,需要注意以下两点:

  • 数值类型和string类型之间的相互转换可能造成值部分丢失;其他的转换仅是类型的转换,不会造成值的改变。string和数字之间的转换可使用标准库strconv。
  • Go语言没有语言机制支持指针和interger之间的直接转换,可以使用标准库中的unsafe包进行处理。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【促销定价】背后的算法技术 2 - 数据预处理生成

【促销定价】背后的算法技术 2 - 数据预处理生成 01 数据探查02 数据清洗03 数据聚合04 数据补全05 小结参考文献 导读:在日常生活中,我们经常会遇见线上/线下商家推出各类打折、满减、赠品、新人价、优惠券、捆绑销售等促销活动。一次成功的促销对于消费…

python -- pyQt5中 样式设置

一、父控件设置样式表后对子控件产生影响,控制styleSheet的作用范围 https://blog.csdn.net/qq_31073871/article/details/90288625 QFrame 作为容器,放入其他多种部件,里面的边框都生效 在类名后面用 #号串接变量名,子控件不…

Required request parameter ‘ids‘ for method parameter type List is not present]

在写delete方法的时候,出现了bug 于是将RequestParam换成PathVariable 两者有何区别? pathVariable和RequestParam的区别 在Spring MVC框架中,PathVariable 和 RequestParam 是两种用于从HTTP请求中获取参数的注解,它们的区别…

Flask vs Django:我该选择哪一个?

大家好!在选择适合自己的Web开发框架时,Flask和Django都是开发者最喜欢的Python Web应用框架。 在本文章中给大家介绍如何正确选择以及优缺点对比,喜欢记得收藏、关注、点赞。 一,Flask Flask是一个轻量级的Web应用框架&#x…

决策树:理解机器学习中的关键算法

决策树:理解机器学习中的关键算法 决策树是一种流行而强大的机器学习算法,它从数据中学习并模拟决策过程,以便对新的未知数据做出预测。由于其直观性和易理解性,决策树成为了分类和回归任务中的首选算法之一。在本文中&#xff0…

2024最新外贸建站:SiteGround主机购买使用及自建外贸独立站教程

原文来源:https://guomuyu.com/building-website-siteground.html 在开始之前,让我们先了解一下什么是外贸独立站。外贸独立站简单来说就是一个拥有独立域名的网站,它不依赖于第三方平台(如阿里巴巴、亚马逊等)的网站…

Python--闭包

在 Python 中,闭包是一种函数,它能够记住并访问其所在词法作用域(即定义该函数的作用域)中的变量,即使该函数在其词法作用域之外被调用。要形成闭包,需要满足以下几个条件: 必须有一个内嵌函数&…

介绍 QT 的 QGraphicsView 和 QGraphicsScene

当绘制复杂的图形或实现交互式图形应用程序时,可以使用 QGraphicsView 和 QGraphicsScene 来进行绘图。 QGraphicsScene: QGraphicsScene 是一个场景,可以容纳和管理图形项(QGraphicsItem)。它提供了一个二维坐标系统…

网页设计与网站建设作业html+css+js,一个简易的游戏官网网页

一个简易的游戏网页 浏览器查看 目录结构 部分代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport&…

重学Java 5 idea详细使用和运算符

慢点跑&#xff0c;前面的路不好走 ——24.1.14 一、IDEA的使用 1.idea的介绍 1.概述&#xff1a;开发工具 2.特点&#xff1a; a、idea是java写的&#xff0c;所以本地上必须有正确的jdk环境 b、idea自动保存 c、不用我们打开dos命令窗口执行javac和java命令 d、idea有强大的…

Mnajora 使用deb包安装软件

说明 Mnajora 安装deb软件包主要有两种方式 可以使用dpkg 直接安装也可是使用debtap将deb软件包转换成 使用dpkg sudo pacman -S dpkg #安装dpkgsudo dpkg -i ###.deb #使用dpkg安装deb软件包和在ubuntu上是一样的 安装成功 使用debtap debtap是一个用于将.deb包转换为A…

236.【2023年华为OD机试真题(C卷)】生成哈夫曼树(优先搜索(DFS)-JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目二.解题思路三.题解代码Python题解代码JAVA题解…

第 2 课 ROS 系统安装和环境搭建

文章目录 方法一&#xff1a;一键安装&#xff08;推荐&#xff09;方法二&#xff1a;逐步安装&#xff08;常规安装方式&#xff09;1.版本选择2.检查 Ubuntu 的软件和更新源3.设置 ROS 的下载源3.1 设置国内下载源3.2 设置公匙3.3 更新软件包 4. 安装 ROS5. 设置环境变量6. …

(每日持续更新)jdk api之FileFilter基础、应用、实战

博主18年的互联网软件开发经验&#xff0c;从一名程序员小白逐步成为了一名架构师&#xff0c;我想通过平台将经验分享给大家&#xff0c;因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验&#xff0c;晚上进行用心精简、整理、总结、定稿&…

鸿蒙Harmony-PersistentStorage--持久化存储UI状态储详解

用简单的心境&#xff0c;对待复杂的人生&#xff0c;方能看淡得失&#xff0c;从容入世&#xff0c;潇洒自如&#xff0c;心变得简单了&#xff0c;世界也就简单了 目录 一&#xff0c;定义 二&#xff0c;限制条件 三&#xff0c;使用 一&#xff0c;定义 LocalStorage和App…

midjournery教程(可以在微信中免费使用)

图片比例 9:16 --ar 9:16 图片风格化 --s 1000 --stylize 1000 版本 Midjourney 定期发布新模型版本以提高效率、一致性和质量。默认为最新型号&#xff0c;但可以使用--version或--v参数或使用/settings命令并选择型号版本来使用其他型号。不同的模型擅长处理不同类型的图…

【ASP.NET Core 基础知识】--中间件--内置中间件的使用

ASP.NET Core 中包含很多内置的中间件&#xff0c;我们不可能对每一个内置的中间件进行一一讲解&#xff0c;并且中间件的使用步骤大致一样&#xff0c;因此本文讲解几个常用的内置中间件以及使用中间件的步骤&#xff0c;希望读者们可以举一反三。 一、内置中间件的介绍 1.1…

爬虫-6-数据提取-beautifulsoup4

#声明:本文仅供学习。 (●—●)

12.3在应用层使用SPI总线

在SPI总线驱动框架中提供了一个spidev 的字符设备驱动&#xff0c;在应用层可以通过它来访问SPI总线。 应用层访问SPI总线的步骤 编写spidev设备树节点&#xff0c;在SPI总线的设备树节点下添加spidev设备的树节点&#xff0c;设备树示例如下所示&#xff1a; spidev0: spid…

沉浸式webview输入框被输入法遮挡了怎么办?!

还是那个倒霉的双十一需求&#xff0c;测试时发现发弹幕的输入框被系统输入法挡住了&#xff0c;这个问题在之前UC内核的浏览器时没问题啊。经过各种对比定位&#xff0c;发现是因为这次需求还有个沉浸式的实现&#xff0c;就是这个实现导致输入框无法被弹起。所幸看到了Androi…