Golang基础数据类型

本节介绍Golang的基本数据类型,字符串,整型,浮点型,数组,切片

类型 长度(字节 byte) 默认值 说明
bool 1 false
byte 1 0 uint8
rune 4 0 Unicode Code Point, int32
int, uint 8 0 32 或 64 位
int8, uint8 1 0 -128 ~ 127, 0 ~ 255,byte是uint8 的别名
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 函数

注意项:

  • float32大约可以提供小数点后6位的精度,作为对比,float64可以提供小数点后15位的精度。通常情况应该优先选择float64,因此float32的精确度较低,在累积计算时误差扩散很快,而且float32能精确表达的最小正整数并不大,因为浮点数和整数的底层解释方式完全不同 https://studygolang.com/articles/6429

一,字符串

1,字符串长度与拼接
    var name = "小明!"
    say := "Hello,This is my City"

    fmt.Println(len(name)) // 9 一个汉字 占3个字节
    fmt.Println(len(say)) // 21 英文字母和空格,都占一个字节

    fmt.Println(name + " " + say) // + 号可用于字符串拼接  // 小明! Hello,This is my City
    fmt.Printf("%v %v \n",name,say) // 小明! Hello,This is my City
2,字符串分割
    arr := strings.Split(say," ")  //返回一个切片:[]string
    fmt.Println(arr) // [Hello,This is my City]
    fmt.Println(len(arr)) // 4
    fmt.Println(cap(arr)) // 4
3,判断是否包含
    exist := strings.Contains(name,"小")
    fmt.Println(exist) // true
4,判断子串出现位置,如果没有出现,返回 -1
    idx := strings.Index(say,"i") //第一个出现的位置
    fmt.Println(idx) // 8 ,是从 0 开始的
    fmt.Println(strings.LastIndex(say,"i")) // 18
5,切片合并成字符串
    fruits := []string{"苹果","橘子","香蕉"}
    fmt.Println(strings.Join(fruits,",")) // 苹果,橘子,香蕉
    fmt.Println(reflect.TypeOf(strings.Join(fruits,","))) // string
6,字符串转整形(有两个返回值,处理err)
    var strNum1 = "123"
    var strNum2 = "123.456"

    num1,err := strconv.Atoi(strNum1)
    if err != nil {
        num1 = 0
    }
    fmt.Println(num1) // 123

    num2,err2 := strconv.Atoi(strNum2)
    if err2 != nil {
        fmt.Println(err2)  //strconv.Atoi: parsing "123.456": invalid syntax
        num2 = 0 //被触发,同理,strNum2 = "123.0"也会被触发
    }
    fmt.Println(num2) // 0
7,字符串转浮点型:
    num3,err3 := strconv.ParseFloat(strNum1,32)
    if err3 != nil {
        num3 = 0
    }
    fmt.Println(num3) // 123

    num4,err4 := strconv.ParseFloat(strNum2,64)
    if err4 != nil {
        num4 = 0
    }
    fmt.Println(num4) //123.456

二,整形与浮点型

1,数字类型之间互相转换:
    var num6 int64 = 100
    var num7 float64 = 123.356
    fmt.Println(reflect.TypeOf( int32(num6) )) // int32
    fmt.Println(reflect.TypeOf( float64(num6) )) //float64

同理,还有int8() , int16() , int64() , float32() 等函数

2,整形转字符串:
    str1 := strconv.Itoa( int(num6) ) //这个函数只能传入int类型的,不能传入int64等其他整型的,淦
    fmt.Println(str1) // 100
3,浮点型转字符串:
    str2 := strconv.FormatFloat(num7,'f',2,64)
    fmt.Println(str2) // 123.36

三,数组

func main()  {
    // 1,声明:元素类型 元素个数
    var strList [5]string
    fmt.Println(strList) //[    ] 声明一个数组后会自动设置其默认值

    var numList [5]int
    fmt.Println(numList) //[0 0 0 0 0]

    //2,声明,并初始化
    var list3 =  [5]int{1,2,3}
    fmt.Println(list3) //[1 2 3 0 0]

    //3,声明,初始化,自动识别数组个数:
    var list4 = [...]int{1,2,3,4}
    fmt.Println(list4) //[1 2 3 4]
    fmt.Println(cap(list4)) //[1 2 3 4]
    fmt.Println(len(list4)) //[1 2 3 4]

    //4,函数传参与遍历
    getList(list3)

}

func getList(list [5]int){
    //第一种遍历:
    for i := 0; i < len(list); i++ {
        fmt.Println(list[i]);  // 1 2 3 0 0  //通过下标访问元素
    }

    //第二种遍历:
    for key, value := range list {
        fmt.Printf("%v => %v \n",key,value)  // 0 => 1
    }

}

注意事项:

  • 1,数组:是同一种数据类型的固定长度的序列。
  • 2,长度是数组类型的一部分,因此,var a[5] int和var a[10]int是不同的类型。fmt.Println(reflect.TypeOf(list3)) //[5]int
  • 3,访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic
  • 6,数组是值类型,赋值和传参会复制整个数组,而不是指针。因此改变副本的值,不会改变本身的值。
  • 7,支持 "=="、"!=" 操作符,因为内存总是被初始化过的。
  • 8,指针数组 [n]*T,数组指针 *[n]T。
    var list5 = [3]int{1,2,3}
    var list6 = [3]int{1,2,3}
    fmt.Println( list5 == list6 ) //true

    var list7 = [3]int{1,2,4}
    fmt.Println( list6 == list7 ) //false

1,多维数组:

    var list8 = [2][3]int{
        {1,2,3},
        {7,8,9},
    }
    fmt.Println(list8) // [[1 2 3] [7 8 9]]

四,切片

需要说明,slice 并不是数组或数组指针。它通过内部指针和相关属性引用数组片段,以实现变长方案。

  1. 切片:切片是数组的一个引用,因此切片是引用类型。但自身是结构体,值拷贝传递。
  2. 切片的长度可以改变,因此,切片是一个可变的数组。
  3. 切片遍历方式和数组一样,可以用len()求长度。表示可用元素数量,读写操作不能超过该限制。
  4. cap可以求出slice最大扩张容量,不能超出数组限制。0 <= len(slice) <= len(array),其中array是slice引用的数组。
  5. 切片的定义:var 变量名 []类型,比如 var str []string var arr []int。
  6. 空切片等于nil :fmt.Println(slice1 == nil) //true。 如果 slice == nil,那么 len、cap 结果都等于 0。
1,切片的各种定义:
    //切片的声明:1,声明一个不定长数组,
    var slice1 []int
    fmt.Println(slice1) // []
    fmt.Println(slice1 == nil) //true

    slice1 = append(slice1,1) //增加一个元素
    fmt.Println(slice1) // [1]

    //切片的声明:2,通过make函数创建
    var slice2 []int = make([]int,2)// []数据类型 ,长度
    fmt.Println(slice2)

    //slice1[2] = 4 //注意:不可以直接为不存在的键赋值,需要通过append增加后才能 set,get
    slice2 = append(slice2,4)
    fmt.Println(slice2[2]) //4

    //通过截取数组,来生成切片:slice = num[startIndex:endIndex] 如果不填则为默认值:num[0 : max]
    var num =  [5]int{1,3,5,7,9}
    var slice3 = num[:]
    fmt.Println(slice3) //[1 3 5 7 9]

    slice3 = num[1:]
    fmt.Println(slice3) //[3 5 7 9] //可以看到,包含startIndex

    slice3 = num[:2]
    fmt.Println(slice3) //[1 3] //可以看到,不包含endIndex
2,切片的长度
  • len()函数可以获取切片当前长度,cap()函数可以获取切片的最大长度
    var x []int = make([]int,3,5)
    fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x) //len=3 cap=5 slice=[0 0 0]
    x = append(x,1)
    x = append(x,2)
    x = append(x,3)
    x = append(x,4)
    x = append(x,5)
    x = append(x,6)
    x = append(x,1) //经过试验可以发现,make定下的最大长度cap = 5,其实是可以增加到6,7个元素的,并不是最大只能存5个
    x = append(x,1) //当切片长度超过cap时,cap会增长一倍,就是用自己乘以2,直到放得下所增加的元素

    fmt.Println(x)
    fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x) //len=11 cap=20 slice=[0 0 0 1 2 3 4 5 6 1 1]
3,遍历

切片的遍历与上面数组相同
语言范围Range:

  • 1,语法: key,value := range + 变量 : 该用法返回变量中的 元素的 索引和值,如果是集合,则返回key - value 对
  • 2,range + 变量,他有两个返回值,如果某一个返回值你不需要用到,用 _ 接收
4,切片的本质
func main() {
    slice := []int{1, 2, 3, 4, 5}
    fmt.Printf("切片:%v\n", slice) //切片:[1 2 3 4 5]
    fmt.Printf("slice pointer is : %p \n",slice)  // slice pointer is : 0xc00000a2d0
    fmt.Printf("&slice pointer is : %p \n",&slice)  // &slice pointer is : 0xc0000044a0

    changeSlice1(slice)
    fmt.Printf("切片:%v\n", slice) //切片:[1 2 10 4 5]
    fmt.Printf("slice pointer is : %p \n",slice) // slice pointer is : 0xc00000a2d0
    fmt.Printf("&slice pointer is : %p \n",&slice) // &slice pointer is : 0xc0000044a0
}


func changeSlice1(slice []int) {
    slice[2] = 10
    fmt.Printf("切片:%v\n", slice) //切片:[1 2 10 4 5]
    fmt.Printf("slice pointer is : %p \n",slice) // slice pointer is : 0xc00000a2d0
    fmt.Printf("&slice pointer is : %p \n",&slice) // &slice pointer is : 0xc000004520  指针已经不同,可见发生了拷贝
}
  • 1,由上面的代码中可以看到,打印传入函数的slice(值),一直都是 0xc00000a2d0 ,但是这个值的指针:&slice,是不一样了的,证明值经过了拷贝。那为什么函数里面的切片的改变,导致了调用处的切片也一并改变了呢?因为切片的本质就是一个由:保存该切片元素的数组的指针(也就是上面打印出来的0xc00000a2d0 ) + len + cap 的结构体组成,它传了这个值(0xc00000a2d0)进去,进而函数changeSlice1()对这个值所指向的真实数组做处理,从而,导致了调用出的切片的值也发送了改变。
  • 2,Go的参数传递都是值传递,参考资料:https://blog.csdn.net/chen_peng7/article/details/89247047
    image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,864评论 6 494
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,175评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,401评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,170评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,276评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,364评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,401评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,179评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,604评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,902评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,070评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,751评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,380评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,077评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,312评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,924评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,957评论 2 351

推荐阅读更多精彩内容