04 Golang数据类型

learninginto · · 334 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

分类

Go语言中的数据类型分为:基本数据类型和复合数据类型

  • 基本数据类型

整型、浮点型、布尔型、字符串

  • 复合数据类型

数组、切片、结构体、函数、map、通道(channel)、接口等

整型

整型分为以下两个大类:

  1. 有符号整型按长度分:int8、int16、int32、int64
  2. 对应的无符号整型:uint8、uint16、uint32、uint64
  • 定义int类型

默认值为空

var num int = 10
fmt.Printf("num=%v 类型:%T",num, num)
//num=10 类型:int

默认的int类型长度跟随操作系统32/64位而变化

类型 范围 占用空间
int8 -127~128 1B
int16 -32768~32767 2B
int32 -231~231-1 4B
int64 -263~263-1 8B
  • 不同长度的int之间的转换
var a1 int32 = 10
var a2 int64 = 21
fmt.Println(a1 + a2)
//报错,int32和int64为不同类型,不能直接参与运算
fmt.Println(int64(a1) + a2)

高位向底位转换时是直接截取,要注意数值符号

byte和rune类型
  1. uint8类型,或者叫byte型,代表了ASCII的一个字符
  2. rune类型,代表一个UTF-8字符。当需要处理中文、日文或其他复合字符时,需要用到rune类型。rune类型实际是一个int32
var a = 'a'
fmt.Printf("值:%v 类型:%T")
//值:97 类型:int32
fmt.Printf("值:%v 类型:%T")
//值:a 类型:int32

在Go中一个字母占用1个字节,一个汉字占用3个字节(utf-8编码)

var str = "this"
fmt.Println(unsafe.Sizeof(str), len(str))
//16 4

这里不管str的内容是多少,Sizeof始终打印16,与他的内存结构有关;要查看他真实长度的时候,可以用len()方法

Sizeof

查看不同的数据类型,在内存中占用的存储空间(无法查看string类型)

var num int8 = 15
fmt.Println(unsafe.Sizeof(num))
//1
浮点型(与C基本相同)

Go支持两种浮点数:float32和float64,四舍五入保留6位小数,分别占用4B和8B

var num float32 = 3.12
fmt.Println(unsafe.Sizeof(num))//4
var c float64 = 3.14159255
fmt.Printf("%v-%f", c, c)
//3.14159255-3.141592
fmt.Printf("%.2f")
//保留两位小数3.14

Go语言中默认浮点数为float64

  • 科学计数法表示浮点类型

3.14e 表示3.14*102

  • float精度丢失问题

几乎所有的编程语言都有精度丢失的问题,这是典型的二进制浮点数精度损失问题。在定长条件下,二进制小数和十进制小数互转可能有精度丢失。

var num float64 = 1129.6
fmt.Println(num*100)
//112529.9999999999

可以使用第三方包来解决精度损失问题
https://github.com/shopspring/decimal

import(
    "fmt"
    "github.com/shopspring/decimal"
)
func main(){
    m1 := 8.2
    m2 := 3.8
    res := decimal.NewFromFloat(m1).Sub(decimal.NewFromFloat(m2))
    fmt.Println(res)
}
  • int与float之间的转换

int => float

a := 10
b := float64(a)
fmt.Printf("a的类型是%T,b的类型是%T", a, b)
//a的类型是int,b的类型是float
var a1 float32 = 23.4
a2 := float64(a1)
//a1是float32,a2是float64

float => int会直接截取,丢失数据(不建议)

布尔型数据
  1. 布尔型变量默认为false
  2. Go语言中不允许将整型强制转换为布尔型
  3. 布尔型无法参与数值运算,也无法与其他类型转换
字符串

默认值为空,用双引号""包裹值

  • 字符串转义字符
转义符 含义
\r 回车符(返回行首)
\n 换行符(直接跳到下一行的同列位置)
\t 制表符
\' 单引号
\" 双引号
\\ 反斜杠
  • 多行字符串(JS中ES6的模板字符串)
    str := `this
    is
    str
    `
    fmt.Println(str)
  • 字符串的常用操作
方法 说明
len(str) 求长度
+或fmt.Sprintf 拼接字符串
strings.Split 分割
strings.contains 判断是否包含
strings.HasPrefix, strings, HasSuffix 前缀/后缀判断
strings.Index(), strings.LastIndex() 子串出现的位置
strings.Join(a[]string, sep string) 切片转字符串
var str1 = "aaa"
var str2 = "哈喽"
var str3 = "123-456-789"
fmt.Println(len(str1), len(str2))//4 6
fmt.Sprintf("%v %v", str1, str2)//aaa 哈喽

arr := strings.Split(str,"-")
fmt.Println(arr)//切片[123 456 789]
fmt.Println(strings.Join(arr, "-"))//123-456-789

newArr := []string{"php","JavaScript","golang"}
fmt.Pringln(string.Join(newArr))//[php JavaScript golang]

str10 := "this is str"
str11 := "this"
flag := strings.Contains(str10, str11)
//判断str10中是否包含true

fmt.Println("strings.HasPrefix(str10, str11)")//判断str1是否以str2开头
fmt.Println("strings.HasSuffix(str10, str11)")//判断str2是否以str2结尾

fmt.Println(strings.Index(str10, str11))
//判断str11在str10中首次出现的位置 0
fmt.Println(strings.LastIndex(str10, "is"))
//判断str11在str10中最后出现的位置(位置始终按照从左往右计算)5

  • 循环遍历字符串
s := "hello"
for i :=0; i < len(s); i++ {//byte
    fmt.Printf("%v(%c)", s[i], s[i])
}
fmt.Println()
//打印有问题,因为一个汉字占用了3个字节
for _,r := range s {//rune
    fmt.Printf("%v(%c)", r, r)
}
  • 修改字符串

要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。

s1 := "big"
byteS1 := []byte(s1)
byteS1[0] = "p"
fmt.Println(string(byteS1))//pig
s2 := "胡萝卜"
runeS2 := []rune(s2)
runeS2[0] = '白'
fmt.Println(string(runeS2))//白萝卜
  • sprintf

string=>other. sprintf使用中需要注意转换的格式

int为%d float为%f bool为%t byte为%c

var i int = 20
var f float64 = 12.456
var t tool = true
var b byte = 'a'
str := fmt.Sprintf("%d", i)
fmt.Printf("%v%T", str, str)//20string
str2 := fmt.Sprintf("%.2f", f)
fmt.Printf("%v%T", str2, str2)//12.46string
str3 := fmt.Sprintf("t", f)
fmt.Printf("%v %T", str3, str3)//true string
str4 := fmt.Sprintf("%c", b)
fmt.Printf("%v %T")//a string
  • ParseInt(string数据,进制,位数)

ParseInt方法有两个返回值,一个是转换的结果,一个是返回的错误信息

str := "123456"
fmt.Printf("%v%T\n", str, str)
num, _ := strconv.ParseInt(str, 10, 64)
fmt.Printf("%v%T",num, num)//123456 int64
  • ParseFloat(string数据,位数)
str := 123.456
num, _ := strconv.ParseFloat(str, 64)//123.456 float64
  • strconv包

其他类型转string类型

1.int=>string: 该方法中接收两个参数,参数1:int64的数值;参数2:当前int类型的进制

var i int = 20
str1 := strconv.FormatInt(int64(i), 10)
fmt.Printf("%v%T", str1, str1)//20string
var f float = 20.32
str2 := strconf.FormatFloat
  1. float=>string: 接收四个参数
    参数1:传入的值;
    参数2:格式化的方式 'f'(-ddd.dddd)……;
    参数3:保留的小数点(-1表示不对小数点格式化);
    参数4:格式化的类型(传入64/32)
var f float32 = 3.141592
str := strconv.FormatFloat(float64(f), 'f', 4, 64)
fmt.Printf("%v%T", str, str)//3.1416 string
  1. bool=>string
str := strconv.FormatBool(true)
fmt.Printf("%v%T", str, str)//true string

数值型无法和bool类型转换

  1. 字符=>string
a := 'b'
str := strconv.FormatUint(uint64(a), 10)
fmt.Printf("%v%T", str, str)//98 string
自定义类型和类型别名
//自定义类型
type myInt int
//类型别名
type myFloat  = float64

func main(){
    var a myInt = 10
    fmt.Printf("%v %T", a, a) //10 main.myInt
    var b myFloat = 123.4
    fmt.Printf("%v %T", b, b) //123.4 float64
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:learninginto

查看原文:04 Golang数据类型

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

334 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传