前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言知识查漏补缺|基本数据类型

Go语言知识查漏补缺|基本数据类型

作者头像
白泽z
发布2022-12-20 11:48:08
4810
发布2022-12-20 11:48:08
举报
文章被收录于专栏:Go与云原生开发Go与云原生开发

前言

学习Go半年之后,我决定重新开始阅读《The Go Programing Language》,对书中涉及重点进行全面讲解,这是Go语言知识查漏补缺系列的文章第二篇,前一篇文章则对应书中一二两章。

我也开源了一个Go语言的学习仓库,有需要的同学可以关注,其中将整理往期精彩文章、以及Go相关电子书等资料。

仓库地址:https://github.com/BaiZe1998/go-learning

第三章、基本数据类型

3.1 整数

负数的%运算

&^(位运算符:and not),x &^ y = z,y中1的位,则z中对应为0,否则z中对应为x中的位

代码语言:javascript
复制
00100010 &^ 00000110 = 00100000

无符号整数通常不会用于只为了存放非负整数变量,只有当涉及到位运算、特殊的算数运算、hash等需要利用无符号特性的场景下才会去选择使用

比如数组下标i用int存放,而不是uint,因为i--使得i == -1时作为判断遍历结束的标志,如果是uint,则0减1则等于2^64-1,而不是-1,无法结束遍历

注意:int的范围随着当前机器决定是32位还是64位

代码语言:javascript
复制
var x int32 = 1
var y int16 = 2
var z int = x + y // complie error
var z int = int(x) + int(y) // ok
// 大多数数值型的类型转换不会改变值的内容,只会改变其类型(编译器解释这个变量的方式),但是当整数和浮点数以及大范围类型与小范围类型转换时,可能会丢失精度,或者出现意外的结果

3.2 浮点数

代码语言:javascript
复制
math.MaxFloat32
math.MinFloat32
const x = 6.2222334e30 // 科学计数法
// math包中有很多的使用浮点数的函数,并且fmt包有很多适用于浮点数的格式化输出,包括保留小数点的具体精度等

float32精度大概6位

float64精度大概15位(更常用,因为单精度计算损失太快)

代码语言:javascript
复制
// 直接用浮点数为返回值结果,再二次用于其他的比较判断返回结果是否有效,有时会有误差导致错误,推荐额外增加一个bool参数
func compute() (value float64, ok bool) {
  if failed {
    return 0, false
  }
  return result, true
}

3.3 复数

代码语言:javascript
复制
var x complex128 = complex(1, 2) // 1+2i
var y complex128 = complex(3, 4) // 3+4i
fmt.Println(x*y) // -5+10i
fmt.Println(real(x*y)) // -5
fmt.Println(imag(x*y)) // 10
// 两个复数相等当且仅当实部和虚部相当
fmt.Println(cmplx.Sqrt(-1)) // 0+1i

3.4 布尔量

bool是if或者for的判断条件

代码语言:javascript
复制
s != "" && s[0] == 'x' // 当逻辑运算符左侧表达式可以决定操作结果则将放弃执行右侧表达式
// &&的优先级高于||

3.5 字符串

string在GO语言中是不可变的量

len获取的是字符串的字节数目,而不是码点(UTF-8 Unicode code point)

字符串第i个字节,并不一定是字符串的第i个字符,因为UTF-8编码对于非ASCII的code point需要2个或更多字节

代码语言:javascript
复制
str := "hello, world"
fmt.Println(s[:5]) // hello
fmt.Println(s[7:]) // world
fmt.Println(s[:]) // hello world

s := "left"
t := s
s += " right" // 此时s指向新创建的string ”left right“,而t指向之前的s表示的“left”

a := "x"
b := "x"
a == b // true,且string可以按照字典序比较大小

string是不可变的,意味着同一个string的拷贝可以共享底层的内存,使得拷贝变得很轻量,比如s和s[:7]可以安全的共享相同的数据,因此substring操作也很轻量。没有新的内存被分配。

反引号中的字符串表示其原生的意思,内容可以多行定义,不支持转义字符

代码语言:javascript
复制
func main() {
  a := `hello 
  world
  lalala`
  fmt.Println(a)
}
Unicode

UTF-8使用码点描述字符(Unicode code point),在Go中对应术语:rune(GO中使用int32存储)

可以使用一个int32的序列,来代表rune序列,固定长度带来了额外的开销(因为大多数常用字符可以使用16bits描述)

UTF-8

可变长编码,使用1-4 bytes来代表一个rune,1byte存储 ASCII ,2 or 3 bytes 存储大多数常用字符 rune,并且采用高位固定的方式来区分范围(前缀编码,无二义性,编码更紧凑)

image-20220823214937576

代码语言:javascript
复制
s := "Hello, 世界"
fmt.Println(len(s)) // 13
fmt.Println(utf8.RuneCountInString(s)) // 9
字符串和数组切片

字符串包含了一连串的字节(byte),创建后不可变。而[]byte内容是可变的

代码语言:javascript
复制
s := "abc"
b := []byte(s) // 分配新的字节数组内存
s2 : string(b) // 发生内存拷贝

为了避免没有必要的转换和内存分配,bytes包中提供了很多与string包中相同功能的方法,更推荐使用(共享内存)

bytes.Buffer用于字符(字符串)的累加构造字符串操作很方便,高效

代码语言:javascript
复制
// 一些操作Buffer的api
var buf bytes.Buffer
fmt.Fprintf(&buf, "%d", x)
buf.WriteString("abc")
buf.WriteByte('x')
buf.WriteRune(码点值)
字符串和数值类型的转换
代码语言:javascript
复制
// 整数转string
x := 123
y := fmt.Sprintf("%d", x)
fmt.Println(y, strconv,Itoa(x)) // "123" "123"
// %b %d %u %x 用于进制转换
s := fmt.Sprintf("x=%b", x) // "x=1111011"
// string转整数
x, err := strconv.Atoi("123")
y, err := strconv.ParseInt("123", 10, 64)// base 10, up to 64 bits,第三个参数表示转换的整型的范围为int64
// fmt.Scanf()可以用于读取混合数据(整型、字符等)

3.6 常量

所有常量的底层都是由:boolean、string、number组成(在编译时确定,不可变,常量的运算结果依旧是常量)

代码语言:javascript
复制
const a = 2
const b = 2*a // b 在编译时完成

大多数常量的声明没有指定类型,但是也可以指定,没有类型的常量Go中称为无类型常量(untyped constant),具体的类型到使用到的时候确定

untyped constant
代码语言:javascript
复制
const a = 10
fmt.Printf("%T\n", a) // int(隐式类型)
var b float64 = 4*a // 在需要的时候,a转变成了float64
fmt.Printf("%T\n", b) // float64

在默认情况下,untyped constant 不是没有具体类型,而是隐式转换成了如下类型,因此上述a的类型可以打印为int

并且untyped constant拥有更高的精度,可以认为至少有 256bit 的运算精度

  • • untyped boolean
  • • untyped integer (隐式转换成 int)
  • • untyped rune (隐式转换成 int32)
  • • untyped floaing-point (隐式转换成 float64)
  • • untyped complex (隐匿转换成 complex128)
  • • untyped string
常量生成器

可以参与计算且拥有增长属性

代码语言:javascript
复制
type Flags uint
const (
  a = 1 << iota // 1
  b             // 2
  c             // 4
  d             // 8
)
const (
  _ = 1 << (10 * iota)
  KiB // 2^10
  MiB // 2^20
  GiB // 2^30
  TiB // 
  PiB // 
  EiB // 
  ZiB // 2^70
  ...
)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-08-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员白泽 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 第三章、基本数据类型
    • 3.1 整数
      • 3.2 浮点数
        • 3.3 复数
          • 3.4 布尔量
            • 3.5 字符串
              • Unicode
              • UTF-8
              • 字符串和数组切片
              • 字符串和数值类型的转换
            • 3.6 常量
              • untyped constant
              • 常量生成器
          相关产品与服务
          对象存储
          对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档