Golang 更明确的数字类型命名,支持 Unicode,支持常用数据结构。
类型 | 长度(字节) | 默认值 | 说明 |
---|---|---|---|
bool | 1 | false | |
byte | 1 | 0 | uint8 |
rune | 4 | 0 | Unicode Code Point, int32 |
int, uint | 4或8 | 0 | 32 或 64 位 |
int8, uint8 | 1 | 0 | -128 ~ 127, 0 ~ 255,byte是uint8 的别名 |
int16, uint16 | 2 | 0 | -32768 ~ 32767, 0 ~ 65535 |
int32, uint32 | 4 | 0 | -21亿~ 21亿, 0 ~ 42亿,rune是int32 的别名 |
int64, uint64 | 8 | 0 | |
float32 | 4 | 0.0 | |
float64 | 8 | 0.0 | |
complex64 | 8 | ||
complex128 | 16 | ||
uintptr | 4或8 | 以存储指针的 uint32 或 uint64 整数 | |
array | 值类型 | ||
struct | 值类型 | ||
string | “” | UTF-8 字符串 | |
slice | nil | 引用类型 | |
map | nil | 引用类型 | |
channel | nil | 引用类型 | |
interface | nil | 接口 | |
function | nil | 函数 |
基本数据类型
整型
整型分为以下两个大类:
按长度分为:int8
、int16
、int32
、int64
对应的无符号整型:uint8
、uint16
、uint32
、uint64
8bit(位)=1Byte(字节) 1024Byte(字节)=1KB 1024KB=1MB 1024MB=1GB 1024GB=1TB 。在电脑里一个中文字是占两个字节的。
而且注意类型范围~(避免出现如下报错)
package main
import (
"fmt"
)
func main() {
var num int64
num = 123
fmt.Printf("值:%v 类型%T", num, num)
}
unsafe.Sizeof
package main
import (
"fmt"
"unsafe"
)
func main() {
var a int8 = 120
fmt.Printf("%T\n", a)
fmt.Println(unsafe.Sizeof(a))
}
package main
import (
"fmt"
"unsafe"
)
func main() {
var (
num int8 = 122
num01 int16 = 20000
num02 int16 = -30000
num03 uint8 = 12
)
fmt.Printf("num的值为%v,类型为%T\n",num,num)
fmt.Printf("num01的值为%v,类型为%T\n",num01,num01)
fmt.Printf("num02的值为%v,类型为%T\n",num02,num02)
fmt.Printf("num03的值为%v,类型为%T\n",num03,num03)
fmt.Println("占用字节为",unsafe.Sizeof(num))
fmt.Println(unsafe.Sizeof(num01))
fmt.Println(unsafe.Sizeof(num02))
fmt.Println(unsafe.Sizeof(num03))
}
int 不同长度直接的转换
注意:int类型不一致的无法进行运算(且高转低的时候要注意范围,可能不在范围内,且符号喝非符号字段也要注意)
package main
import (
"fmt"
// "unsafe"
)
func main() {
var (
a int8 = 18
b int16 = 2000
)
fmt.Println(int16(a)+b)
}
数字字面量语法
v := 0b00101101, 代表二进制的 101101,相当于十进制的 45。
v := 0o377,代表八进制的377,相当于十进制的 255。
v := 0x1p-2,代表十六进制的 1 除以 2²,也就是 0.25。 而且还允许我们用 _ 来分隔数字,比如说: v := 123_456 等于 123456。
package main
import "fmt"
func main(){
// 十进制
var a int
a = 10
fmt.Printf("%d \n", a) // 10
fmt.Printf("%b \n", a) // 1010 占位符%b 表示二进制
// 八进制 以 0 开头
var b int
b = 077
fmt.Printf("%o \n", b) // 77
// 十六进制 以 0x 开头
var c int
c = 0xff
fmt.Printf("%x \n", c) // ff
fmt.Printf("%X \n", c) // FF
fmt.Printf("%d \n", c) // 255
}
浮点型
注意:
底层存储空间和操作系统无关
浮点类型底层存储:符号位+指数位+尾数位,所以尾数位只是存了 一个大概,很可能会出现精度的损失。
Go语言支持两种浮点型数:float32
和float64
。
package main
import "fmt"
func main(){
//定义浮点类型的数据:
var num1 float32 = 3.14
fmt.Println(num1)
//可以表示正浮点数,也可以表示负的浮点数
var num2 float32 = -3.14
fmt.Println(num2)
//浮点数可以用十进制表示形式,也可以用科学计数法表示形式 E 大写小写都可以的
var num3 float32 = 314E-2
fmt.Println(num3)
var num4 float32 = 314E+2
fmt.Println(num4)
var num5 float32 = 314e+2
fmt.Println(num5)
var num6 float64 = 314e+2
fmt.Println(num6)
这两种浮点型数据格式遵循IEEE 754
标准:
float32
的浮点数的最大范围约为3.4e38
,可以使用常量定义math.MaxFloat32
。
float64
的浮点数的最大范围约为 1.8e308
,可以使用一个常量定义:math.MaxFloat64
。
浮点型数据搭配%f占位符:%f默认为保持6个小数%f的其他作用:类似python的占位写法(m.n%f)表示保留m个数目,.n表示小数点后留几位
package main
import (
"fmt"
"unsafe"
)
func main() {
flot := 2.14
fmt.Printf("%f\n", flot) //默认保留 6 位小数
fmt.Printf("%3.2f\n", flot) //保留 2 位小数
var a float32 = 3.14
fmt.Printf("值为%v--%f,类型%T\n", a, a, a) //3.14--3.140000,类型float32
fmt.Println(unsafe.Sizeof(a)) //占4个字节
var b float64 = 2.13
fmt.Printf("值为%v--%f,类型%T\n", b, b, b) //值:2.13--2.130000,类型float64
fmt.Println(unsafe.Sizeof(b)) //占8个字节
64位的系统中 浮点数默认是 float64
package main
import (
"fmt"
// "unsafe"
)
func main() {
tes1 := 3.1345656456 // 64位的系统中 浮点数默认是 float64
fmt.Printf("%f--%T", tes1, tes1)
Golang 科学计数法表示浮点类型
package main
import (
"fmt"
// "unsafe"
)
func main() {
var f2 float32 = 3.14e2 //表示f2等于3.14*10的2次方
fmt.Printf("%v--%T\n", f2, f2)
var f3 float32 = 3.14e-2 //表示f3等于3.14除以10的2次方
fmt.Printf("%v--%T\n", f3, f3)
Golang 中 float 精度丢失问题
package main
import (
"fmt"
// "unsafe"
)
func main() {
var num1 float64 = 1129.6
fmt.Println(num1 * 100)
num2 := 8.2
num3 := 3.8
fmt.Println(num2 - num3)
例如num1期望输出为112960,num2-num3期望输出4.4 ,但是实际结果为:
int类型转换成float类型
package main
import (
"fmt"
// "unsafe"
)
func main() {
a := 10
b := float64(a)
fmt.Printf("a的类型是%T,b的类型是%T\n", a, b)
var a1 float32 = 23.4
a2 := float64(a1)
fmt.Printf("a1的类型是%T,a2的类型是%T\n", a1, a2)
不建议float类型转换成int类型
var c1 float32 = 23.45
c2 := int(c1)
fmt.Printf("c2的值:%v c2的类型:%T", c2, c2)
可以实现,但是会缺失数据
布尔值
var flag bool = true
fmt.Println(flag)
var flag01 bool = false
fmt.Println(flag01)
var flag02 bool = 3 < 9
fmt.Println(flag02)
package main
import (
"fmt"
// "unsafe"
)
func main() {
var flag = true
fmt.Printf("%v--%T\n", flag, flag)
// 1.布尔类型变量的默认值为false。
var b bool
fmt.Printf("%v\n", b)
// 2.string型变量的默认值为空。
var s string
fmt.Printf("%v\n", s)
// 3.int型变量的默认值为0。
var i int
fmt.Printf("%v\n", i)
// 4.float型变量的默认值为0。
var f float32
fmt.Printf("%v\n", f)
string型变量的默认值为空;int和float型变量的默认值为0
Go 语言中不允许将整型强制转换为布尔型,且布尔型无法参与数值运算,也无法与其他类型进行转换,比如下面的错误写法:
package main
import (
"fmt"
// "unsafe"
)
func main() {
var a = 2
if a {
fmt.Printf("true")
}
var s = "this is str"
if s {
fmt.Printf("true")
}
var f1 = false
if f1 { //正确写法
fmt.Printf("true")
} else {
fmt.Printf("false")
}
字符串
字符串转义符
Go 语言的字符串常见转义符包含回车、换行、单双引号、制表符等,如下表所示。
转义 | 含义 |
---|---|
\r | 回车符(返回行首) |
\n | 换行符(直接跳到下一行的同列位置) |
\t | 制表符 |
' | 单引号 |
" | 双引号 |
\ | 反斜杠 |
1、定义string类型,1个汉字是3个字节
var str1 string = "你好golang"
var str2 = "你好 卫宫士郎"
str3 := "你好golang"
fmt.Printf("%v--%T\n", str1, str1)
fmt.Printf("%v--%T\n", str2, str2)
fmt.Printf("%v--%T\n", str3, str3)
str4 := "卫宫士郎"
str5 := "sabar"
str6 := str4 + str5
fmt.Printf("字符串为%v,其类型为%T",str6,str6)
2、字符串转义符
package main
import (
_ "strings"
"fmt"
// "unsafe"
)
func main() {
//2、字符串转义符
fate := "Steel is my body \nand fire is my blood"
fmt.Println(fate)
str1 := "I am the bone of my sword"
fmt.Println(str1)
str2 := "C:\\卫宫士郎\\sabar"
fmt.Println(str2)
// 其实就是去除原本的意思
3、多行字符串
sabar := `
I have created over a thousand blades
Unknown to Death
Nor known to Life
Have withstood pain to create many weapons
`
fmt.Println(sabar)
4、len(str) 求长度
servant := "I have created over a thousand blades"
fmt.Println(len(servant))
5、+ 或者 fmt.Sprintf拼接字符串
str1 := "反引号间换行将被作为字符串中的换" +
"文本将会原样输出" +
"行,但是所有的转义字符均无效"
fmt.Println(str1)
// rider := "吾为所持剑之骨\n"
// archer := "此身为剑之骨\n"
// str := rider + archer
// str1 := fmt.Sprintf("%v,%v",rider,archer)
// fmt.Println(str)
// fmt.Println(str1)
str2 := `
I am the bone of my sword
Steel is my body,and fire is my blood
`
fmt.Println(str2)
6、strings.Split 分割字符串 strings需要引入strings包
package main
import (
"strings"
"fmt"
// "unsafe"
)
func main() {
lancer := "Have withstood pain to create many weapons"
str7 := strings.Split(lancer," ")
fmt.Println(str7)
//简单的理解切片就是数组 在golang中切片和数组还有一些区别
7、strings.Join(a[]string, sep string) join 操作 表示把切片链接成字符串
lancer := "Have withstood pain to create many weapons"
str7 := strings.Split(lancer," ")
str8 := strings.Join(str7,"--")
fmt.Print(str8)
fmt.Print("\n--------------------\n")
str01 := []string{"archer", "sabar", "golang"}
str03 := strings.Join(str01,"-")
fmt.Println(str03)
8、 strings.contains 判断是否包含
lancer := "Have withstood pain to create many weapons"
str04 := "pain"
flag := strings.Contains(lancer,str04)
fmt.Print(flag)
9、strings.HasPrefix,strings.HasSuffix 前缀/后缀判断
lancer := "Have withstood pain to create many weapons"
str04 := "Have"
flag01 := strings.HasPrefix(lancer,str04)
fmt.Println(flag01)
sabar := "this is archer"
str05 := "archer"
flag02 := strings.HasSuffix(sabar,str05)
fmt.Println(flag02)
10、 strings.Index(),strings.LastIndex() 子串出现的位置
查找不到返回-1 查找到正向返回下标位置 下标是从0开始的
rider := "this is a"
str04 := "t"
num := strings.Index(rider,str04)
fmt.Println(num)
fmt.Print("\n--------------------\n")
baskets := "this is a"
str05 := "is" //0 1 2 找到了返回位置
num01 := strings.Index(baskets,str05)
fmt.Print(num01)
fmt.Print("\n--------------------\n")
baskets01 := "this is a"
str06 := "is" //从后往前找到的是中间的is,然后正向坐标位置数为5
num02 := strings.LastIndex(baskets01,str06)
fmt.Print(num02)
fmt.Print("\n--------------------\n")
baskets02 := "this is a"
str07 := "lancer" //找不到位置为-1
num03 := strings.Index(baskets02,str07)
fmt.Print(num03)
byte 和 rune 类型
组成每个字符串的元素叫做“字符”,可以通过遍历或者单个获取字符串元素获得字符。 字符用单引号(’)包裹起来,如:
var a := '中'
var b := 'x'
Go 语言的字符有以下两种:
uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。
rune类型,代表一个 UTF-8字符。
当需要处理中文、日文或者其他复合字符时,则需要用到rune
类型。
rune
类型实际是一个int32
。
Go 使用了特殊的 rune
类型来处理 Unicode
,让基于 Unicode
的文本处理更为方便,也可以使用 byte
型进行默认字符串处理,性能和扩展性都有照顾。
1、golang中定义字符 字符属于int类型
a := 'a'
fmt.Printf("对应的ascll码值为%v,类型为%T,值为%c",a,a,a)
//当我们直接输出 byte(字符)的时候输出的是这个字符对应的码值
2、定义一个字符串输出字符串里面的字符
str := "tomshebly"
fmt.Printf("对应的ascll码值为%v,类型为%T,值为%c",str[1],str[1],str[1])
3 查看存储空间
unsafe.Sizeof() 没法查看string类型数据所占用的存储空间
str := "tomshebly"
fmt.Println("占用字节为",len(str))
str0 := "汤"
fmt.Println("占用字节为",len(str0))
一个汉字占用3个字节,而一个字母占用一个字节
4、定义一个字符 字符的值是汉字
golang中汉子使用的是utf8编码 编码后的值就是int类型
ascll转unicode编码10进制
str1 := '姆'
fmt.Printf("对应的ascll值为%v,类型为%T,原值为%c",str1,str1,str1)
在线 Unicode 编码转换 | 菜鸟工具 (runoob.com)
5、通过循环输出字符串里面的字符
str := "卫宫士郎sabar"
for i := 0 ; i < len(str);i++{
fmt.Printf("值为%v,类型为%T\n",str[i],str[i])
}
// 注意这个地方,一个汉字占用3个字节,而一个字母占用一个字节,如果连带汉字的字符串要正常输出需要使用range
str := "卫宫士郎sabar"
for _ , s := range str{
fmt.Printf("值为%v,类型为%T,原值为%c\n",s,s,s)
}
6、修改字符串,要修改字符串,需要先将其转换成[]rune 或[]byte,完成后再转换为 string。
str01 := "卫宫士郎"
changstr :=[]rune(str01)
changstr[0] = '本'
fmt.Println(string(changstr))
str02 := "tomsher"
changstr0 := []byte(str02)
changstr0[0] = 'L'
fmt.Println(string(changstr0))
golang 中的数据类型转换
注意:转换的时候建议从 低位转换成高位,高位转换成低位的时候如果转换不成功就会溢出,和我们想的结果不一样。
数值类型之间的相互转换
数值类型包括 :整形和浮点型
1、整型和整型之间的转换
类型不同,不能相互加减
2、浮点型和浮点型之间的转换
var a float32 = 20
var b float64 = 40
fmt.Println(float64(a) + b)
3、整型和浮点型之间的转换(建议整型转换为浮点型,浮点型别转整形)
var a float32 = 20.23
var b int = 40
fmt.Println(a + float32(b))
其他类型转换成 String 类型
1、sprintf 把其他类型转换成 string 类型
注意:sprintf 使用中需要注意转换的格式int 为%dfloat 为%fbool 为%tbyte 为%c
var i int = 8
var f float64 = 13.1415926
var t bool = true
var b byte = 'a'
str1 := fmt.Sprintf("%d", i)
fmt.Printf("值:%v 类型:%T\n", str1, str1)
str2 := fmt.Sprintf("%.2f", f)
fmt.Printf("值:%v 类型:%T\n", str2, str2)
str3 := fmt.Sprintf("%t", t)
fmt.Printf("值:%v 类型:%T\n", str3, str3)
str4 := fmt.Sprintf("%c", b)
fmt.Printf("值:%v 类型:%T\n", str4, str4)
2、通过strconv 把其他类型转换成string类型
1、int转 string
var a int = 10
str := strconv.FormatInt(int64(a),10)
fmt.Printf("值为%v 类型为%T\n", str, str)
参数解释:
FormatInt
参数1:int64 的数值
参数2:传值int类型的进制
2、float 转 string(有四个参数需要添加)
参数 1:要转换的值
参数 2:格式化类型 'f'(-ddd.dddd)、
'b'(-ddddp±ddd,指数为二进制)、
'e'(-d.dddde±dd,十进制指数)、
'E'(-d.ddddE±dd,十进制指数)、
'g'(指数很大时用'e'格式,否则'f'格式)、
'G'(指数很大时用'E'格式,否则'f'格式)。
参数 3: 保留的小数点 -1(不对小数点格式化)
参数 4:格式化的类型 传入 64 32
var flot float32 = 13.1415926
str01 := strconv.FormatFloat(float64(flot),'f',4,32)
fmt.Printf("输出的值为%v,类型为%T",str01,str01)
3、bool 转 string和int64 转 string没有意义
int64 转 string(第二个参数为 进制 )
str3 := strconv.FormatBool(true) //没有任何意义
fmt.Printf("值:%v 类型:%T\n", str3, str3)
a := 'b' //没有任何意义
str4 := strconv.FormatUint(uint64(a), 10)
fmt.Printf("值:%v 类型:%T\n", str4, str4) //值:98 类型:string
String 类型转换成数值类型
1、string类型转换成整型(int)
这里需要注意:
string转int类型时候,会返回两个值
一个是转换后的int,一个是err报错(转换失败);
这里我们采取省略_下划线来搞
ParseInt
参数1:string数据
参数2:进制
参数3:位数 32 64 16
str := "123456"
num, _ := strconv.ParseInt(str, 10, 64)
fmt.Printf("%v--%T", num, num)
2、string 类型转换成 float 类型
ParseFloat
参数1:string数据
参数2:位数 32 64
这是错误写法:
str := "1.131413asda"
num, _ := strconv.ParseFloat(str, 64)
fmt.Printf("%v--%T", num, num)
str := "123456.333"
num, _ := strconv.ParseFloat(str, 64)
fmt.Printf("%v--%T", num, num)
3、string 类型转换成 bool 类型(没意义)
b, _ := strconv.ParseBool("true") // string 转 bool
fmt.Printf("值:%v 类型:%T", b, b)