Golang入门2-数据类型

因为数据类型跟变量息息相关,所以这里会先讲述Golang变量的几种声明方式。

1.var name type比如 var i int, 表示声明了一个int类型的变量,名字为 i。这时候只是声明,并没有赋值,如果变量没有赋值,Go会自动进行赋值,而int类型的默认值为0。

2.var name type = value第一种方式的进化,在声明变量的时候便赋予了初始值

3.var name = value(类型推断)比如 int i = 8, 此时虽然没有声明i的类型,但是Go会自动识别 i 的类型

4.var name1, name2 type = value1, value2声明多个变量

5.name := value(简短声明)这是Golang的一种典型声明方式, 例如 i := 1。这种方式有三个要求,一是要求左边的变量必须被赋值,二是要求左边变量至少有一个是尚未声明的,三是这种方式只支持函数体内使用,其他范围必须用var

// 左边的变量必须被赋值
func main(){
    name, age := "your name"  // assignment mismatch: 2 variable but 1 values
    fmt.Println("my name is", name, "age", age)
}

// 左边变量至少有一个是尚未声明的
func main(){
    a, b := 20, 30
    fmt.Println("a is ", a, "b is", b)
    // 因为c未声明,所以运行成功
    b, c := 40, 50
    fmt.Println("b is ", b, "c is", c)
}
复制代码

在Golang中, 公有变量和私有变量
也值得注意,其中,首字母大写的变量(包括函数)是公有变量,可以被其他模块引用; 首字母小写的变量是私有变量,只能在本模块引用

package main

import (
    "fmt"
    "math"
)
func main() {
    fmt.Println(math.Pi) // 3.141592653589793
}
// 错误示范
func main() {
    fmt.Println(math.pi) // cannot refer to unexported name math.pi
}

复制代码

正餐

Golang有非常多的类型,这里只会涉及到 数字类型
字符串类型

数字类型

Go的数字类型有很多,具体有以下类型:

  • int8, int16, int32, int64, int
  • uint8, uint16, uint32, uint64, uint
  • float32, float64
  • complex64, complex128
  • byte
  • rune

有符号整型int8:表示 8 位有符号整型(00000000 ~ 11111111, 第一位是符号位)
大小:8 位
范围:-128~127

int16:表示 16 位有符号整型
大小:16 位
范围:-32768~32767

int32:表示 32 位有符号整型
大小:32 位
范围:-2147483648~2147483647

int64:表示 64 位有符号整型
大小:64 位
范围:-9223372036854775808~9223372036854775807
int:根据不同的底层平台自动选择 32 或 64 位整型。除非对整型的大小有特定的需求,否则你通常应该使用 int 表示整型。

无符号整型uint8:表示 8 位无符号整型
大小:8 位
范围:0~255

uint16:表示 16 位无符号整型
大小:16 位
范围:0~65535

uint32:表示 32 位无符号整型
大小:32 位
范围:0~4294967295

uint64:表示 64 位无符号整型
大小:64 位
范围:0~18446744073709551615

uint:根据不同的底层平台,选择 32 或 64 位无符号整型。
大小:在 32 位系统下是 32 位,而在 64 位系统下是 64 位。
范围:在 32 位系统下是 0~4294967295,而在 64 位系统是 0~18446744073709551615。

浮点型
float32:32 位浮点数
float64:64 位浮点数

复数类型
complex64:实部和虚部都是 float32 类型的的复数。
complex128:实部和虚部都是 float64 类型的的复数。

复数类型的实部和虚部应该是相同类型,也就是 float32 或 float64。
如果实部和虚部都是 float32 类型,则函数会返回一个 complex64 类型的复数。如果实部和虚部都是 float64 类型,则函数会返回一个 complex128 类型的复数。

其他数字类型
byte 是 uint8 的别名。创建这个类型是为了区分传过来的参数是位类型还是数字类型
rune 是 int32 的别名。
nil: pointer, channel, func, interface, map, or slice 类型的0值, 也只能用于这些类型

package main

import (
    "fmt"
    "unsafe"
)

func main()  {
    // unsafe.Sizeof用于查看变量的字节数
    var a uint8 = 124
    var b uint16 = 124
    var c uint32 = 124
    var d uint64 = 124
    var e int = 2147483649

    var g int8 = 124
    // var f int8 = -156  // 这样赋值会报错, 因为int8的范围是-128~127, 所以赋值为-156会溢出
    var i int16 = 124
    var k int32 = 124
    fmt.Println("sizea:", unsafe.Sizeof(a))  // 占1个字节
    fmt.Println("sizeb:", unsafe.Sizeof(b))  // 2
    fmt.Println("size:", unsafe.Sizeof(c))  // 4
    fmt.Println("size:", unsafe.Sizeof(d))  // 8
    fmt.Println("size:", unsafe.Sizeof(e))  // 我的机器是64位,所以是8字节

    //fmt.Println("size:", unsafe.Sizeof(f))  // 1
    fmt.Println("size:", unsafe.Sizeof(g))  // 1
    fmt.Println("size:", unsafe.Sizeof(i))  // 2
    fmt.Println("size:", unsafe.Sizeof(k))  // 4
}

复制代码

字符串类型

由于和其他语言相比,字符串在 Go 语言中有着自己特殊的实现,主要有以下几个特点。

  • 1.字符串是字节的集合。
  • 2.单引号和双引号代表的意义不同, 单引号是rune类型,双引号才是字符串类型。
  • 3.Go 中的字符串是兼容 Unicode 编码的,并且使用 UTF-8 进行编码。

获取字符串长度的几种方法:

  • 使用 bytes.Count() 统计
  • 使用 strings.Count() 统计
  • 将字符串转换为 []rune 后调用 len 函数进行统计
  • 使用 utf8.RuneCountInString() 统计
str:="HelloWord"
 
l1:=len([]rune(str))
 
l2:=bytes.Count([]byte(str),nil)-1)
 
l3:=strings.Count(str,"")-1
 
l4:=utf8.RuneCountInString(str)
复制代码

单引号和双引号的区别?
在Go中,双引号是用来表示字符串string,其实质是一个byte类型的数组。单引号表示rune类型。还有一个反引号, 支持多行文本,但不支持转义。

字符串的格式化
studygolang.com/articles/10…

类型转换

// 1.数字类型转字符串类型主要有三种方法: fmt.Sprint、strconv.Itoa和strconv.FormatInt。
// 其中, fmt.Sprintf效率是最低的, 由于strconv.Itoa封装了strconv.FormatInt, 所以效率在第二位, strconv.FormatInt效率最高。

// uint32 to string
var n uint32 = 42
string := fmt.Sprint(n)

var n uint32 = 42
string := strconv.FormatUint(uint64(n), 10)

// int to string
string := strconv.Itoa(int)

// int64 to string
string := strconv.FormatInt(int64, 10)

// string to int
i, err := strconv.Atoi(str)
if err == nil {
  fmt.Printf(“i: %v\n”,i)
}

// string to int64
i64,err := strconv.ParseInt(str, 10, 64)
if err == nil {
  fmt.Printf(“i64: %v\n”,i64)
}
复制代码