go学习 3、基础数据类型

news2024/11/24 12:29:50

3、基础数据类型

  • 基础数据类型:数字、字符串、布尔型
  • 复合类型:数组、结构体
  • 引用类型:指针、切片、字典、函数、通道
  • 接口类型

3.1 整型

有符号、无符号 int8/int16/int32/int64 uint8/uint16/uint32/units 64
Unicode字符rune类型是和int32等价的类型,通常用来表示一个Unicode码点,这两个名称可以互换使用。
byte和unit8是等价类型,byte类型一般用于强调数值是一个原始的数据而不是一个小的整数。
一种无符号的整数类型unitptr,没有指定具体的bit大小但是足以容纳指针。只有在底层编程时才需要。
int 和int32也是不同的类型,即使int的大小也是32bit。需要显式类型转换。
二元运算符:算术运算、逻辑运算、比较运算(优先级顺序)
%取模运算符的符号和被取模数的符号总是一致的。仅用于整数间的运算。 -5%3=-2
数据溢出

^ //位运算XOR,作为二元运算符时是按位异或,用作一元运算符时表示按位取反
&^ //位清空,按位清零
z=x &^ y//y=1,z=0;y=0,z=x

倾向于使用有符号的int类型
八进制前缀0,十六进制前缀0x

o:=0666
fmt.Printf("%d %[1]o %#[1]o\n",o)//438 666 0666

[1]:再次使用第一个操作数
#:输出时生成前缀
字符使用%c参数打印,用%q参数打印带单引号的字符

3.2 浮点数

float32/float64
%g 打印浮点数
对应表格的数据,使用%e(带指数)或%f形式打印可能更合适
math.IsNaN用来测试一个数是否是非数NaN
math.NaN返回非数NaN对应的值

3.3 复数

complex64/complex128 real()实部 imag()虚部
math/cmplx包提供了复数处理的很多函数

3.4 布尔型

true/false

3.5 字符串

字符串是一个不可改变的字节序列。但可以给一个字符串变量分配一个新字符串值。
不变性意味着如果两个字符串共享相同的底层数据的话也是安全的。
文本字符串通常被解释为采用UTF8编码的Unicode码点(rune)序列

s:="left foot"
t:=s
s+=", right foot"
s[0]='L'//编译错误

3.5.1 字符串面值

将一系列字节序列包含包含在双引号,“hello,world”
Go语言源文件总是用UTF8编码,并且Go语言的文本字符串也以UTF8编码的方式处理,因此我们可以将Unicode码点也写到字符串面值中。
在一个双引号包含的字符串面值中,可以用以反斜杠\开头的转义序列插入任意的数据。

\a响铃
\b退格
\f换页
\n换行
\r回车
\t制表符
\v垂直制表符
单引号(只用在‘"形式的rune符号面值中)
‘’双引号(只用在“…”形式的字符串面值中)
\反斜杠
可以通过十六进制或八进制转义在字符串面值包含任意的字节。一个十六进制的转移形式\xhh,其中两个h表示十六进制数字(大写或小写都可以)。一个八进制转义形式是\ooo,包含三个八进制的o数字(0到7),但不能超过\377(对应一个字节的范围,十进制是255)。每一个单一的字节表达一个特定的值。
一个原生的字符面值形式是’…',使用反引号代替双引号。没有转义操作,全部的内容都是字面的意思,包含退格和换行。唯一的特殊处理是会删除回车以保证在所有平台上的值都是一样的。
原生字符串面值用于编写正则表达式会很方便,因为正则表达式往往会包含很多反斜杠。
const GoUsage=’Go is a tool for managing Go source code.

Usage:
	go command [arguments]
...

3.5.2 Unicode

如何有效处理这些包含了各种语言的丰富多样的文本数据呢?
Unicode,它收集了这个世界上所有的符号系统,包括重音符号或其他变音符号,制表符和回车符,还有很多神秘的符号,每个符号都分配一个唯一的Unicode码点,Unicode码点对应Go语言中的rune整数类型。(rune是int32等价类型)
我们可以将一个符文序列表示一个int32序列。编码方式:UTF-32或UCS-4,这种方式比较简单统一,但是它会浪费很多存储空间。
大数据计算机可读的文本是ASCII字符,本来每个ASCII字符只需要8bit或1字节就能表示。常用的字符也远少于65536,16bit编码方式就能表达常用字符。

3.5.3 UTF-8

UTF8是一个将Unicode码点编码为字节序列的变长编码。UTF8编码使用1到4个字节来表示每个Unicode码点,ASCII部分字符只使用1个字节,常用字符部分使用2或3个字节表示。
每个符号编码后第一个字节的高端bit位用于表示总共有多少编码个字节。
如果第一个字节的高端bit为0,则表示对应7bit的ASCII字符,ASCII字符每个字符依然是一个字节,和传统的ASCII编码兼容。
如果第一个字节的高端bit是110,则说明需要2个字节;后续的每个高端bit都以10开头
在这里插入图片描述
变长的编码无法直接通过索引来访问第n个字符,但有优点:

  • UTF8编码比较紧凑,完全兼容ASCII码,并且可以自动同步
  • 它可以通过向前回溯最多2个字节就能确定当前字符编码的开始字节的位置
  • 前缀编码,当从左向右解码时不会有任何歧义也并不需要向前查看。
  • 没有任何字符的编码是其他字符编码的子串,或是其他编码序列的字符,因此搜索一个字符时只要搜索它的字节编码序列即可。
  • UTF8编码的顺序和Unicode码点的顺序一致,可以直接排序UTF8编码序列。
  • 没有嵌入NUL(0)字节,可以很好兼容那些使用NUL作为字符串结尾的编程语言。

Go语言的源文件采用UTF8编码,并且Go语言处理UTF8编码的文本也很出色。unicode包提供了诸多处理rune字符相关功能的函数(区分字母和数组、字母的大写和小写转换),unicode/utf8包提供了用于rune字符序列的UTF8编码和解码的功能。
Unicode转义字符让我们可以通过Unicode码点输入特殊的字符。有两种形式:\uhhh对应16bit的码点值,\Uhhhhhhhh对应32bit的码点值,其中h是一个十六进制数组,一般很少使用32bit的形式。每一个对应码点的UTF8编码。
下面的字母串面值都表示相同的值:
在这里插入图片描述
Unicode转义也可以使用在rune字符中。下面三个字符是等价的:

在这里插入图片描述
对于小于256码点值可以写在一个十六进制转义字节中,例如\x41对应字符’A’,但对于更大码点则必须使用\u或\U转义形式。
得益于UFT8编码优良的设计,诸多字符串操作都不需要解码操作。
不用解码直接测试一个字符串是否是另一个字符串的前缀:

func HasPrefix(s,prefix string) bool{
	return len(s)>=len(prefix)&&s[:len(prefix)]==prefix
}

后缀测试:

func HasSuffix(s,suffix string) bool{
	return len(s)>=len(suffix)&&s[len(s)-len(suffix):]==suffix
}

包含子串测试:

func Contains(s,substr string) bool{
	for i:=0;i<len(s);i++{
		if HasPrefix(s[i:],substr){
			return true
		}
	}
	return false
}

对于UTF8编码后文本的处理和原始的字节处理逻辑是一样的。
内存表示形式

import "unicode/utf8"

s:="Hello, 世界"
fmt.Println(len(s))//13字节
fmt.Println(utf8.RuneCountInString(s))//9个Unicode

为了处理这些真实的字符,我们需要一个UFT8解码器。

for i := 0; i < len(s); {
	//	返回字符本身,字符采用UTF8编码后的编码字节数目
    r, size := utf8.DecodeRuneInString(s[i:])
    fmt.Printf("%d\t%c\n", i, r)
    i += size
}

在这里插入图片描述
Go语言的range循环在处理字符串时,会自动隐式解码UFT8字符串。

for i, r := range "Hello, 世界" { 
	fmt.Printf("%d\t%q\t%d\n", i, r, r)
}

统计字符串中字符的数目:

n := 0
for _, _ = range s {
	n++ 
}
n := 0
for range s {
	n++ 
}

utf8.DecodeRuneInString解码或在range循环中隐式地解码,如果遇到一个错误的UTF8编码输入,将生成Unicode字符\uFFD
UTF8字符串作为交换格式是非常方便的,但是在程序内部采用rune序列可能更方便,rune大小一致,支持数组索引和方便切割。
将[]rune类型转换应用到UTF8编码的字符串,将返回字符串编码的Unicode码点序列:

// "program" in Japanese katakana
s := "プログラム"
//%x参数用于在每个十六进制数字前插入一个空格
fmt.Printf("% x\n", s) // "e3 83 97 e3 83 ad e3 82 b0 e3 83 a9 e3 83 a0" r := []rune(s)
fmt.Printf("%x\n", r) // "[30d7 30ed 30b0 30e9 30e0]"
//如果将一个[]rune类型的Unicode字符slice或数组转为string,则对它们进行UTF8编码
fmt.Println(string(r)) // "プログラム"
//将一个整数转型为字符串:生成以只包含对应Unicode码点字符的UTF8字符串
fmt.Println(string(65)) // "A", not "65"
fmt.Println(string(0x4eac)) // "京"

3.5.4 字符串和Byte切片

  • strings包提供了许多如字符串的查询、替换、比较、截断、拆分和合并等功能
  • bytes包,针对[]byte类型提供很多类似功能的函数。字符串是只读的,逐步构建字符串会导致很多分配和复制。bytes.Buffer类型将会更有效
  • strconv包提供了布尔型、整型数、浮点数和对应字符串的相互转换,还提供了双引号转义相关的转换
  • unicode包提供了IsDigit、IsLetter、IsUpper和IsLower等类似功能,用于字符分类。每个函数有一个单一的rune类型的参数,然后返回一个布尔值。

basename函数
basename(s) 将看起来像是系统路径的前缀删除,同时将看似文件类型的后缀名部分删除

fmt.Println(basename("a/b/c.go")) // "c"
fmt.Println(basename("c.d.go"))   // "c.d"
fmt.Println(basename("abc"))      // "abc"

basename1.go

func basename(s string) string {
    // Discard last '/' and everything before.
    for i := len(s) - 1; i >= 0; i-- {
        if s[i] == '/' {
			s = s[i+1:]
			break
		}
	}
    // Preserve everything before last '.'.
    for i := len(s) - 1; i >= 0; i-- {
        if s[i] == '.' {
			s = s[:i]
			break
		}
	}
	return s 
}

basename2.go

func basename(s string) string {
    slash := strings.LastIndex(s, "/") // -1 if "/" not found
    s = s[slash+1:]
    if dot := strings.LastIndex(s, "."); dot >= 0 {
		s = s[:dot] 
	}
	return s 
}

一个字节slice的元 素则可以自由地修改
字符串和字节slice之间可以相互转换:

s := "abc"
//分配了一个新的字节数组用于保存字符串数据的拷贝,然后 引用这个底层的字节数组
b := []byte(s)
//构造一个字符串拷贝,以确保s2字符串是只读的
s2 := string(b)

为了避免转换中不必要的内存分配,bytes包和strings同时提供了许多实用函数。下面是 strings包中的六个函数:

func Contains(s, substr string) bool
func Count(s, sep string) int
func Fields(s string) []string
func HasPrefix(s, prefix string) bool
func Index(s, sep string) int
func Join(a []string, sep string) string

bytes包中也对应的六个函数:

func Contains(b, subslice []byte) bool
func Count(s, sep []byte) int
func Fields(s []byte) [][]byte
func HasPrefix(s, prefix []byte) bool
func Index(s, sep []byte) int
func Join(s [][]byte, sep []byte) []byte

它们之间唯一的区别是字符串类型参数被替换成了字节slice类型的参数。
bytes包还提供了Buffer类型用于字节slice的缓存。一个Buffer开始是空的,但是随着string、 byte或[]byte等类型数据的写入可以动态增长,一个bytes.Buffer变量并不需要初始化,因为零值也是有效的。

3.5.5 字符串和数字的转换

由strconv包提供字符串和数值之间的转换
将一个整数转为字符串,一种方法是用fmt.Sprintf返回一个格式化的字符串;另一个方法是用strconv.Itoa(“整数到ASCII”):

x := 123
y := fmt.Sprintf("%d", x)
fmt.Println(y, strconv.Itoa(x)) // "123 123"

FormatInt和FormatUint函数可以用不同的进制来格式化数字:

fmt.Println(strconv.FormatInt(int64(x), 2)) // "1111011"

fmt.Printf函数的%b、%d、%o和%x等参数提供功能往往比strconv包的Format函数方便很 多,特别是在需要包含附加额外信息的时候:

s := fmt.Sprintf("x=%b", x) // "x=1111011"

如果要将一个字符串解析为整数,可以使用strconv包的Atoi或ParseInt函数,还有用于解析无 符号整数的ParseUint函数:

x, err := strconv.Atoi("123")             // x is an int
//第三个参数是用于指定整型数的大小;例如16表示int16,0则表示int。
y, err := strconv.ParseInt("123", 10, 64) // base 10, up to 64 bits

fmt.Scanf来解析输入的字符串和数字,特别是当字符串和数字混合在一行的 时候,它可以灵活处理不完整或不规则的输入。

3.6 常量

常量表达式的值在编译器计算,而不是在运行期

 const pi = 3.14159 // approximately; math.Pi is a better approximation

批量声明多个

const (
	e = 2.71828182845904523536028747135266249775724709369995957496696763 
	pi = 3.14159265358979323846264338327950288419716939937510582097494459
)

常量可以是构成类型的一部分,例如用于指定数组类型的长度:

const IPv4Len = 4
// parseIPv4 parses an IPv4 address (d.d.d.d).
func parseIPv4(s string) IP {
    var p [IPv4Len]byte
    // ...
}

一个常量的声明也可以包含一个类型和一个值,但是如果没有显式指明类型,那么将从右边的表达式推断类型。

const noDelay time.Duration = 0
const timeout = 5 * time.Minute
fmt.Printf("%T %[1]v\n", noDelay)     // "time.Duration 0"
fmt.Printf("%T %[1]v\n", timeout)     // "time.Duration 5m0s"
fmt.Printf("%T %[1]v\n", time.Minute) // "time.Duration 1m0s"

如果是批量声明的常量,除了第一个外其它的常量右边的初始化表达式都可以省略,如果省略初始化表达式则表示使用前面常量的初始化表达式写法,对应的常量类型也一样的

const ( 
	a=1
	b 
	c=2 
	d
)
fmt.Println(a, b, c, d) // "1 1 2 2"

3.6.1 iota常量生成器

常量声明可以使用iota常量生成器初始化,它用于生成一组以相似规则初始化的常量,但是不 用每行都写一遍初始化表达式。在一个const声明语句中,在第一个声明的常量所在的行, iota将会被置为0,然后在每一个有常量声明的行加一。

type Weekday int
const (
    Sunday Weekday = iota//0
    Monday //1
    Tuesday //2
    Wednesday
    Thursday
    Friday
    Saturday
)

例子:给一个无符号整数的最低5bit的每个bit指定一个名字:

type Flags uint
const (
    FlagUp Flags = 1 << iota // is up
	FlagBroadcast// supports broadcast access capability
	FlagLoopback// is a loopback interface
	FlagPointToPoint// belongs to a point-to-point link
	FlagMulticast// supports multicast access capability
)

随着iota的递增,每个常量对应表达式1 << iota,是连续的2的幂,分别对应一个bit位置
iota局限性:它并不能用于产生1000的幂(KB、MB等),因 为Go语言并没有计算幂的运算符。

3.6.2 无类型常量

六种未明确类型的常量类型:无类型的布尔型、无类型的整数、无类型的字符、无类型的浮点数、无类型的复数、无类型的字符串
通过延迟明确常量的具体类型,无类型的常量不仅可以提供更高的运算精度,而且可以直接 用于更多的表达式而不需要显式的类型转换。
只有常量可以是无类型的。

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

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

相关文章

R语言无法调用stats.dll的问题解决方案[补充]

写在前面 在去年10月份&#xff0c;出过一起关于R语言无法调用stats.dll的问题解决方案,今天&#xff08;你看到后是昨天&#xff09;不知道为什么&#xff0c;安装包&#xff0c;一直安装不了&#xff0c;真的是炸裂了。后面再次把R与Rstuido升级。说实话&#xff0c;我是真不…

整套停车位地磁检测方案出售,主控使用stm32驱动nb-iot模块bc95数据上传远程云服务器。

地磁车辆检测器&#xff0c;是车辆本身含有的铁磁物质会对车辆存在区域的地磁信号产生影响&#xff0c;使车辆存在区域的地球磁力线发生弯曲。当车辆经过传感器附近&#xff0c;传感器能够灵敏感知到信号的变化&#xff0c;经信号分析就可以得到检测目标的相关信息。 朋友创业…

安装github中的存储库作为Python包

第一步&#xff0c;安装git 安装教程&#xff1a;https://zhuanlan.zhihu.com/p/114068278 第二步&#xff0c;在github上复制该库的链接 第三步&#xff0c;使用命令行一键下载并安装包 pip install "githttps://github.com/openai/CLIP.git"如果当pip install…

笔记本充满电后,充电器可以长期不拔,会议安全隐患吗?

笔记本充满电后&#xff0c;一直插着不拔 1.建议人在身边可以暂时不拔&#xff0c;偶尔还是要使用电池当笔记本电池充满之后&#xff0c;电脑会自动使用电源供电&#xff0c;不会使用电池供电 2.笔记本电池都带有电池保护机制&#xff0c;在电池充满电后会自动停止充电 3.现在…

RNN架构解析——认识RNN模型

目录 RNN模型作用分类按照输入和输出的结构进行分类按照RNN的内部构造进行分类 RNN模型 RNN单层网络结构 作用 分类 按照输入和输出的结构进行分类 按照RNN的内部构造进行分类

Ftp和UDP的区别之如何加速文件传输

FTP&#xff08;文件传输协议&#xff09;是一种传输大文件的老方法&#xff0c;它的速度慢&#xff0c;而且容易受到网络环境的影响。在当今这个文件越来越大&#xff0c;项目交付时间越来越紧&#xff0c;工作分布在全球各地的时代&#xff0c;有没有办法让 FTP 加速呢&#…

JS学习第二部分

在前面&#xff0c;第一章节 &#xff0c;学了JS的基本语法和一些常用的用法。在第二章节&#xff0c; 学了DOM&#xff0c;就是节点信息&#xff0c;教我们怎么在JS里面获取HTML的标签。接着&#xff0c;我们学习第三章节&#xff0c;怎么在JS里面对HTML的css样式进行操作。 …

3ds MAX NURBS曲线绘制鼠标

先引用一段大佬的话&#xff0c;解释为什么除了样条线还有这种曲线 NURBS是有理B-splines曲线https://www.zhihu.com/search?q%E6%9C%89%E7%90%86B-splines%E6%9B%B2%E7%BA%BF&search_sourceEntity&hybrid_search_sourceEntity&hybrid_search_extra%7B%22sourceT…

<Postman>Postman接口测试以及使用案例

说明&#xff1a;现在所有的系统都有登录token设置&#xff1b; 所以需要先进行登录&#xff0c;获取两个token&#xff1b; 关于token和refresh token 传统的认证方式一般采用cookie/session来实现&#xff0c;这是我们的出发点。 1.为什么选用token而不选用cookie/session…

OSI模型简介及socket,tcp,http三者之间的区别和原理

1.OSI模型简介&#xff08;七层网络模型&#xff09; OSI 模型(Open System Interconnection model)&#xff1a;一个由国际标准化组织提出的概念模型&#xff0c;试图提供一个使各种不同的计算机和网络在世界范围内实现互联的标准框架。 它将计算机网络体系结构划分为七层,每…

spring 存储对象 + 获取对象

前言 本篇在spring中如何使用五大类注释与方法注释将对象加入IOC容器中&#xff0c;了解如何使用注释来获取容器中的Bean对象&#xff0c;如有错误&#xff0c;请在评论区指正&#xff0c;让我们一起交流&#xff0c;共同进步&#xff01; 文章目录 前言1.通过注释将类加入IoC…

【C++ 重要知识点总结】自定义类型-类和结构体

类 类的基本特性 数据抽象和封装继承多态 1 类的构成——抽象 概念 数据抽象是一种依赖于接口和实现的分离的编程技术。类的接口包括用户所能执行的操作&#xff1b;类的实现包括类的数据成员、负责接口实现的函数体以及定义类所需要的的各种私有函数。封装实现了类的接口和实…

645. 错误的集合

645. 错误的集合 class Solution { public static int[] findErrorNums(int[] nums) {Arrays.sort(nums);int dup-1;int miss1;for (int i 1; i < nums.length; i) {if(nums[i]nums[i-1]){dupnums[i];}if(nums[i]-nums[i-1]>1){missnums[i]-1;}}return new int[]{dup,…

Vmware vSphere 5.0系列

Vmware vSphere 5.0 我们都用过 vmware workstation 这款产品&#xff0c;可以使我们安装很多虚拟机&#xff0c;但是 vmware 的核心产品远非局限于 workstation。 vSphere 是 VMware 推出的基于云的新一代数据中心虚拟化套件&#xff0c;提供了虚拟化基础架构、高可用性、集…

Tesseract开源的OCR工具及python pytesseract安装使用

一 、介绍 Tesseract是一款由Google赞助的开源OCR。 pytesseract是python包装器&#xff0c;它为可执行文件提供了pythonic API。 Tesseract 已经有 30 年历史&#xff0c;开始它是惠普实验室的一款专利软件&#xff0c;在2005年后由Google接手并进一步开发和完善。Tesseract支…

【Unity 实用插件篇】| 可视化图表插件XCharts (折线图、柱状图、饼图等)详细教学

前言 【Unity 实用插件篇】| 可视化图表插件XCharts (折线图、柱状图、饼图等)详细教学一、XCharts介绍1.1 特性1.2 相关网站链接1.3 效果展示 二、XCharts导入三、XCharts快速使用3.1 添加一个简单图表3.2 添加多个Seire3.3 给图表添加其他组件3.4 添加Serie组件&#xff0c;如…

什么是Maven,Maven的概述及基本使用

MAVEN 一、Maven简介1.1、Maven概述1.2、Maven仓库1.3项目获取jar包过程 二、Maven使用2.1Maven安装配置2.1.1配置环境变量2.1.2配置本地仓库2.1.3配置阿里云私服 2.2Maven基本使用2.2.1Maven常用指令2.2.2Maven生命周期 总结 一、Maven简介 Apache Maven是一个项目管理和构建…

自动驾驶数据标注有哪些?

自动驾驶汽车&#xff1a;人工智能(AI)的焦点 人工智能驱动汽车解决方案的市场规模预计到 2025年将增长十倍以上&#xff0c;提升车内体验的商机领域以及 AI 模型的无偏见训练数据的重要性。在本篇中&#xff0c;我们将介绍车外体验的关键组成部分&#xff0c;以及自动驾驶数据…

Python 爬虫的学习 day01 ,爬虫的基本知识, requests 和 charde模块, get函数的使用

1.Python 爬虫 1.1什么是网络爬虫 网络爬虫&#xff0c;又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取万维网信息的程序或者脚本&#xff0c;另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。 1.2 网络爬虫的特…

2023/7/26总结

最近都花时间在项目上 修改了发布文章的界面 然后文章可以上传图片了 修改了个人主页的界面&#xff08;这里把js代码注释掉了&#xff0c;所以没用内容&#xff09; 大概画了一下管理员的界面 和消息列表的界面 做了评论的界面&#xff1a;&#xff08;还没开始写&#xff0c…