Go基础学习04-变量重声明;类型转换;类型断言;Unicode代码点;类型别名;潜在类型

目录

变量重声明

类型断言

类型转换

 类型转换注意事项

Unicode代码点

类型别名、潜在类型

  类型别名的意义


变量重声明

编写代码:

package mainimport "fmt"var container = []string{"Beijing", "Shanghai"}func main() {fmt.Println(container)container = []string{"Hello", "Hi"}fmt.Printf("variable redeclare %s\n", container)container := map[int]string{1: "Beijing", 2: "Shanghai"}strings, ok := interface{}(container).([]string)if ok {fmt.Println("Container type is []string...")fmt.Println(strings)} else {fmt.Println("Container type is map...")fmt.Printf("strings is %v\n", strings)}fmt.Println(container)
}

        上述代码首先定义一个字符串数组,其名称为container,在main函数中,首先对container进行短变量重赋值,随后又对container使用短变量重新赋值,但这次赋值的对象类型不是[]string而是一个map类型,其key为int,value为string。此时产生的现象在Go中称为可重名变量的类型不同,原先类型为[]string,随后将其类型更改为map[int][string]。上述代码执行结果如下:

        在使用:=对变量进行重声明之后,如果前后对应的变量类型不一致,此时一般需要进行类型断言,来确定具体变量对应的类型如:是[]string还是map[int][string]以确定后面遍历操作。

        下面将补充一下类型转换以及类型断言相关知识: 

类型断言

        在本篇开篇提供的代码中:

         上述方框中的.([]string)就是类型断言:

        类型断言表达式的语法形式是x.(T)。其中的x代表要被判断类型的那个值。这个值当下的类型必须是接口类型的,不过具体是哪个接口类型其实是无所谓的。所以,当这里的container变量类型不是任何的接口类型时,我们就需要先把它转成某个接口类型的值(具体参考下面类型转换知识)。如果container是某个接口类型的,那么这个类型断言表达式就可以是container.([]string)。

        这里使用类型断言将接口类型转换为[]string,同时类型断言等式左边有两个变量,变量ok表示是否能将接口类型变量断言为字符串数组,如果可以断言,则ok值为true同时转换后的字符串数组结果存储到strings变量中;如果不能将接口类型的变量转换为字符串数组,此时ok的值为false,并且strings值为[](nil)参考上面代码运行结果。

类型转换

        类型转换的语法形式是T(x)。
        其中的x可以是一个变量,也可以是一个代表值的字面量(比如1.23和struct{}),还可以是一个表达式。如果是表达式,那么该表达式的结果只能是一个值,而不能是多个值。在这个上下文中,x可以被叫做源值,它的类型就是源类型,而那个T代表的类型就是目标类型。

        如果从源类型到目标类型的转换是不合法的,那么就会引发一个编译错误。

strings, ok := interface{}(container).([]string)

        上面代码中的interface{}(containter)就是类型转换,当container不是一个接口类型时,通过类型转换将其转换为接口类型。在Go语言中,interface{}代表空接口,任何类型都是它的实现类型。任何类型的值都可以很方便地被转换成空接口的值。

        关于上面interface{}中的{}的解释参考下面图片: 

 类型转换注意事项

对于类型转换而言常见的需要遵循的转换规则如下:

  1. 对于整数类型值、整数常量之间的类型转换,原则上只要源值在目标类型的可表示范围内
    就是合法的。
    1. uint8(255)可以把无类型的常量255转换为uint8类型的值,是因为255在 [0,255] 的范围内。但需要特别注意的是,源整数类型的可表示范围较大,而目标类型的可表示范围较小的情况,比如把值的类型从int16转换为int8,此时会涉及到类型值的截断(大范围变为小范围可能涉及到值的缩小)。
  2. 虽然直接把一个整数值转换为一个string类型的值是可行的,但值得关注的是,被转换
    的整数值应该可以代表一个有效的 Unicode 代码点,否则转换的结果将会是"�"(仅由高亮的问号组成的字符串值)。具体关于Unicode代码点的解释可以参考下面阐述。
  3. string类型与各种切片类型之间的互转需要遵守类型编码规则,如UTF-8编码或者其他形式。

         代码展示:

package mainimport ("fmt""strconv"
)func main() {// 类型转换范围限定演练srcNum := int16(-255)dstNum := int8(srcNum)fmt.Printf("srcNum:%d, dstNum:%d\n", srcNum, dstNum)/**Go语言中负数以补码的形式存在,补码:源码求反+1-255 :1111111100000001从16位转为8位,需要高位截断变为00000001,由于最高位是0所以表示正数,所以是1*//**Go中有效的Unicode代码点是什么???在将一个整数值转换为字符串时,这个整数应该是一个有效的 Unicode 代码点的值。Unicode 是一个字符编码标准,它为世界上大多数的文字系统提供了一个唯一的码位。每个 Unicode 代码点都对应一个字符。在计算机中,字符通常以字节的形式存储,而每个字节可以表示 0 到 255 之间的整数值。当一个整数超出了这个范围,或者它不是一个有效的 Unicode 代码点时,尝试将它转换为字符串可能会导致无法正确显示该字符,从而出现替代字符,通常是 ""(一个黑色菱形,中间有一个问号)。例如,在 UTF-8 编码中,一个字符可能由一到四个字节表示。如果一个整数对应于一个超出常用 Unicode 字符范围的值(比如大于 0x10FFFF),或者它是一个用于表示字符属性的码点(比如一些控制字符),那么它可能无法被正确地转换为一个可打印的字符。在 Go 语言中,如果你使用 string() 函数将一个整数值转换为字符串,并且该值超出了有效的 Unicode 代码点范围,你可能会得到一个替代字符。为了避免这个问题,你应该确保转换的整数值在有效的 Unicode 范围内(通常是 0 到 0x10FFFF)。*/fmt.Println(string(65))fmt.Println(string(37))fmt.Println(string(-1))/**正确的将整数转为字符串应该使用Go中提供的转换工具如:strconv.Itoa()\strconv.FormatInt()*/num := -1fmt.Println(strconv.Itoa(num))fmt.Println(strconv.FormatInt(int64(num), 10))
}

        结果展示:

Unicode代码点

        在将一个整数值转换为字符串时,这个整数应该是一个有效的 Unicode 代码点的值。Unicode 是一个字符编码标准,它为世界上大多数的文字系统提供了一个唯一的码位。每个 Unicode 代码点都对应一个字符。 在计算机中,字符通常以字节的形式存储,而每个字节可以表示 0 到 255 之间的整数值。当一个整数超出了这个范围,或者它不是一个有效的 Unicode 代码点时,尝试将它转换为字符串可能会导致无法正确显示该字符,从而出现替代字符,通常是 ""(一个黑色菱形,中间有一个问号)。 例如,在 UTF-8 编码中,一个字符可能由一到四个字节表示。如果一个整数对应于一个超出常用 Unicode 字符范围的值(比如大于 0x10FFFF),或者它是一个用于表示字符属性的码点(比如一些控制字符),那么它可能无法被正确地转换为一个可打印的字符。 在 Go 语言中,如果你使用 string() 函数将一个整数值转换为字符串,并且该值超出了有效的 Unicode 代码点范围,你可能会得到一个替代字符。为了避免这个问题,你应该确保转换的整数值在有效的 Unicode 范围内(通常是 0 到 0x10FFFF)。

        Unicode代码点可以借助ASCII码表理解,如A对应的整数类型值为65,这一部分可以借助上面代码理解。

类型别名、潜在类型

        在Go语言中,可以使用关键字type声明自定义的各种类型,这些类型必须在Go语言基本类型和高级范畴之内。下面介绍类型别名以及潜在类型。

type Mystring = string

       这条声明语句表示,MyString是string类型的别名类型。顾名思义,别名类型与其源类型的
区别恐怕只是在名称上,它们是完全相同的。

        源类型与别名类型是一对概念,是两个对立的称呼。别名类型主要是为了代码重构而存在的。在Go语言中已经存在的有别名类型如:byte是unit8的类型别名,rune是int32的类型别名。

type Mystring string

        上述Mystring和string是两个不同的类型,Mstring是一个新的类型,不同于其他任何类型。

        这种方式也可以被叫做对类型的再定义。我们刚刚把string类型再定义成了另外一个类型Mystring。对于这里的类型再定义来说,string可以被称为Mystring的潜在类型。潜在类型的含义:
        某个类型在本质上是哪个类型或者是哪个类型的集合。潜在类型相同的不同类型的值之间是可以进行类型转换的。        

        因此,Mystring类型的值与string类型的值可以使用类型转换表达式进行互转。但对于集合类的类型[]Mystring与[]string来说这样做却是不合法的,因为[]Mystring与[]string的潜在类型不同,分别是Mystring和string。另外,即使两个类型的潜在类型相同,它们的值之间也不能进行判等或比较,它们的变量之间也不能赋值。

        代码演示:

 

package mainimport ("fmt"
)// 潜在类型
type MyString string// 类型别名
type MyString2 = stringfunc main() {var name MyStringname = "zhang san"var copyName string/**潜在类型相同的不同类型的值之间是可以进行类型转换的。即使两个类型的潜在类型相同,但这两个类型对应的变量之间也不能进行判等或者比较,也不能进行赋值,只能进行类型转换copyName = name 不允许的操作*/copyName = string(name)fmt.Println(name)fmt.Println(copyName)fmt.Println("=========================")var name2 MyString2name2 = "lisi"var copyName2 stringcopyName2 = name2fmt.Println(name2)fmt.Println(copyName2)
}

  类型别名的意义

        对于大型的代码库来说,能够重构其整体结构是非常重要的,包括修改某些 API 所属的包。大型重构应该支持一个过渡期:从旧位置和新位置获得的 API 都应该是可用的,而且可以混合使
用这些 API 的引用。Go 已经为常量、函数或变量的重构提供了可行的机制,但是并不支持类
型。类型别名提供了一种机制,它可以使得 oldpkg.OldType 和 newpkg.NewType 是相同的,并且引用旧名称的代码与引用新名称的代码可以互相操作。

        考虑将一个类型从一个包移动到另一个包中的情况,比如从 oldpkg.OldType 到newpkg.NewType。可以在包 oldpkg 中指定一个新类型的别名 type OldType = newpkg.NewType,这样以前的代码都无需修改。

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

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

相关文章

关于Python升级以后脚本不能运行的问题

近日将Python从3.11升级到了3.12,然后把几个包例如numpy等也通过pip给upgrade了一下,结果原来运行的好好的脚本,都运行不了了,还出现各种报错。怀疑是自己升级了环境导致的,因此通过搜索引擎检索了一下,有这…

两个月学习大语言模型(LLM)的详细计划,保姆级教程非常详细收藏我这一篇就够了!

随着人工智能技术的发展,大语言模型(Large Language Models, LLMs)因其在自然语言处理、机器翻译、文本生成等领域的广泛应用而受到越来越多的关注。对于希望掌握这一前沿技术的朋友来说,制定一个系统的学习计划至关重要。本计划旨…

ATTCK实战系列-Vulnstack靶场内网域渗透(二)

ATT&CK实战系列-Vulnstack靶场内网域渗透(二) 前言一、环境搭建1.1 靶场下载地址1.2 环境配置1.2.1 DC域控服务器:1.2.2 WEB服务器:1.2.3 PC域内主机:1.2.4 攻击者kali: 1.3 靶场拓扑图 二、外网渗透2.…

Ubuntu磁盘不足扩容

1.问题 Ubuntu磁盘不足扩容 2.解决方法 安装一下 sudo apt-get install gpartedsudo gparted

Selenium 自动化测试:如何搭建自动化测试环境?

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 最近也有很多人私下问我,selenium学习难吗,基础入门的学习内容很多是3以前的版本资料,对于有基础的人来说,3到4的差…

mybaits获取sqlsession对象后自动开启事务,增删改要记得提交事务!

mybaits中在使用 SQLSession 对象进行数据库操作时,需要注意事务的处理。 以下是关于这个问题的详细说明: 一、SQLSession 与事务的关系 SQLSession 是 MyBatis 框架中用于执行 SQL 语句和与数据库交互的关键对象。当获取 SQLSession 对象后&#xff…

2024年主流前端框架的比较和选择指南

在选择前端框架时,开发者通常会考虑多个因素,包括框架的功能、性能、易用性、社区支持和学习曲线等。以下是一些主流前端框架的比较和选择指南。 1. 主流前端框架简介 React 优点: 组件化开发,易于复用和维护。虚拟DOM提高了性能。强大的生…

每日算法1(快慢指针)

通过一道题来了解快慢指针 这是一道力扣的算法题,首先来读题,是删除链表的中间元素,先来分析一下题,链表一共有三种可能,第一种是空链表,第二种链表的个数是偶数,第三种是链表的个数是奇数&…

【ARM】MDK-当选择AC5时每次点击build都会全编译

1、 文档目标 解决MDK中选择AC5时每次点击build都会全编译 2、 问题场景 在MDK中点击build时,正常会只进行增量编译,但目前每次点击的时候都会全编译。 3、软硬件环境 1 软件版本:Keil MDK 5.38a 2 电脑环境:Window 10 4、解决…

【计算机视觉】YoloV8-训练与测试教程

✨ Blog’s 主页: 白乐天_ξ( ✿>◡❛) 🌈 个人Motto:他强任他强,清风拂山冈! 💫 欢迎来到我的学习笔记! 制作数据集 Labelme 数据集 数据集选用自己标注的,可参考以下&#xff1a…

企业网盘能作为FTP替代产品吗?

在数字化办公日益普及的今天,企业对于文件存储、传输和协作的需求不断增长。传统的FTP协议虽然在文件传输领域有着不可替代的地位,但其在用户体验、安全性、协作功能等方面逐渐显得力不从心。企业网盘作为一种新兴的数据管理解决方案,正逐渐成…

【前端】前端高级与前端全家桶——学的更深更广一点!

工作太卷了要加油呀! 今天首次参加宣讲会,华测导航的,1/300,太可怕了 What can I do for your company? 前端, 更深一点(JS、算法、底层原理、手写) 当谈及前端开发的学习深度时&#xff0…

多快好省,高质量、低成本通过 CISSP 认证

CISSP 作为安全从业人员含金量最高的认证,一直以来被认为是难度较高、学习成本较大、知识点大而全的考试。这里面也有一部分因素是因为考试费用较高,需要 749$,如果不是公司能够报销通过考试以后的费用,我也不会贸然尝试。相比于国…

关于YOLOX的一些优势

YOLOX 是旷视开源的高性能检测器。旷视的研究者将解耦头、数据增强、无锚点以及标签分类等目 标检测领域的优秀进展与 YOLO 进行了巧妙的集成组合,提出了 YOLOX,不仅实现了超越 YOLOv3、 YOLOv4 和 YOLOv5 的 AP,而且取得了极具竞争力的推理速…

springboot项目引入了第三方jar包

应该把jar包放在resource目录下,新建一个lib目录放进去,不然打包的时候会报错找不到jar包,放入jar包,右键添加到库,才可以使用。 _g().startMarquee();

Allegro视频去除走线的小方块

走线出现小方块图如下: 其实这种情况并不影响PCB生产和布线的联通性,只是多少会影响美观和性能,在Allegro视频中去除的方法比较简单,是由模块复用以后,没有打散模块引起的。只要我们将模块的打散即可。具体操作如下:…

[vulnhub] SickOS1.1

https://www.vulnhub.com/entry/sickos-11,132/ 主机发现端口扫描 探测存活主机,136是靶机,因为靶机是我最后添加的 nmap -sP 192.168.75.0/24 // Starting Nmap 7.93 ( https://nmap.org ) at 2024-09-22 11:36 CST Nmap scan report for 192.168.75.1 …

前端——阿里图标的使用

阿里图标 将小图标定义成字体,通过引入字体的方式来展示这些图标 1.打开阿里图标库 https://www.iconfont.cn/ 2.登录 / 注册一个账号 3.选中你需要使用的图标 并且把它加入购物车 4.全部选择完之后 点击右上角 购物车 然后下载代码 5.解压后你下载的文…

day-59 四数之和

思路 双指针&#xff1a;类似16. 最接近的三数之和&#xff0c;将数组排序后&#xff0c;只需要枚举第一个数&#xff0c;则会变为与第16题相似的解题思路 解题过程 枚举选取的第一个数&#xff0c;0<i<len-3,然后就是第16题的解题思路 Code class Solution {public L…

裸土检测算法实际应用、裸土覆盖检测算法、裸土检测算法

裸土检测算法主要用于环境保护、农业管理、城市规划和土地管理等领域&#xff0c;通过图像识别技术来检测和识别地表上的裸露土壤。这种技术可以帮助管理者实时监控裸土面积&#xff0c;及时采取措施&#xff0c;防止水土流失、环境污染和生态退化。 一、技术实现 裸土检测算…