03Go 类型总结

栏目: Go · 发布时间: 6年前

内容简介:[TOC]Go语言是静态类型语言,不能在运行期间改变变量类型。使用关键字 var 定义变量,自动初始化为零值。如果提供初始化值,可省略变量类型,由编译器自动推断。​ 同一代码块,重新赋值内存地址不变。不同代码块定义同名变量,内存地址不同。

Go 类型总结

[TOC]

1、内置类型和内置函数

内置类型:

类型 ⻓度 默认值 说明
bool 1 false 布尔型只有true和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
int16, uint16 2 0 -32768 ~ 32767, 0 ~ 65535
int32, uint32 4 0 -21亿 ~ 21 亿, 0 ~ 42 亿
int64, uint64 8 0
float32 4 0.0 单精度浮点型 ,小数位:精确到7小数位
float64 8 0.0 双精度浮点型,小数位:精确到15小数位
complex64 8 负数
complex128 16
uintptr 4 或 8 nil ⾜以存储指针的 uint32 或 uint64 整数
array 数组,值类型
struct 结构体,值类型
string "" UTF-8 字符串
slice nil 引⽤类型
map nil 引⽤类型
channel nil 引⽤类型
interface nil 接⼝
function nil 函数
error nil 错误

内置函数:不需要导入就能使用的函数 (了解即可)

函数 说明
append 追加元素到slice,返回修改后的slice
close 用来关闭channel
delete 从map中删除key对应的value
panic 用来做错误处理 panic和rcover
recover 允许程序定义goroutine的panic动作
imag 返回complex的实部,(complex,real imag:操作复数)
real 返回complex的虚部
make 用来分配内存,返回Type本身(只应用于slice,map,channel)
new 用来分配内存,主要用来分配值类型。返回指向Type的指针
cap 用于求最大容量,比如array,slice,channel,返回最大容量
copy 用于赋值和连接slice,返回复制的数目
len 返回长度
print、println 底层打印函数,一般用fmt包的打印

2、类型转换

  • Go中不存在隐式转换,所有类型转换必须显式声明
  • 转换只能发生在两种相互兼容的类型之间
  • int(a) 类型(被转换变量)

3、变量

Go语言是静态类型语言,不能在运行期间改变变量类型。使用关键字 var 定义变量,自动初始化为零值。如果提供初始化值,可省略变量类型,由编译器自动推断。

(1)单个变量声明

var x int                    //使用var
var s = "abc"                //省略类型
s:="abc"                    //函数内部可以省略var

(2)多个变量声明

var x, y, z int                //定义多个
var s, n = "abc", 123        //定义多个省略类型
var (                        //多个,多类型
    a int
    b float32
)
//在函数内部,可⽤更简略的 ":=" ⽅式定义变量
a,b:=128,"12"

(3)多变量赋值时,先计算所有相关值,然后再从左到右依次赋值

data, i := [3]int{0, 1, 2}, 0
i, data[i] = 2, 100 // (i = 0) -> (i = 2), (data[0] = 100)

(4)编译器会将未使⽤的局部变量当做错误

(5)注意重新赋值与定义新同名变量的区别。

​ 同一代码块,重新赋值内存地址不变。不同代码块定义同名变量,内存地址不同。

(6)全局变量、局部变量、形参 以及优先级

4、常量

常量值必须是编译期可确定的数字(整型、浮点型、复数)、字符串、布尔值

(1)单个常量声明

const s string = "Hello, World!"
const s="Hello, World!"

(2)多个常量定义

const x, y int = 1, 2 // 多常量初始化
const (             // 常量组
    a, b = 10, 100
    c bool = false
)

(3)在常量组中,如不提供类型和初始化值,那么视作与上⼀常量相同。

const (
    s = "abc"
    x                 // x = "abc"
)

(4)常量值还可以是 len、 cap、 unsafe.Sizeof 等编译期可确定结果的函数返回值

const (
    a = "abc"
    b = len(a)
    c = unsafe.Sizeof(b)
)

(5)未使用的局部常量不会引发编译错误

(6)枚举:关键字 iota 定义常量组中从 0 开始按⾏计数的⾃增枚举值。

  • 从 0 开始按⾏计数的自增
  • 在同⼀常量组中,可以提供多个 iota,它们各⾃增⻓。
  • 如果 iota ⾃增被打断,须显式恢复。
const (
    _ = iota     // iota = 0
    KB int64 = 1 << (10 * iota) // iota = 1
    MB             // 与 KB 表达式相同,但 iota = 2
)
const (            //在同⼀常量组中,可以提供多个 iota,它们各⾃增⻓。
    A, B = iota, iota << 10 // 0, 0 << 10
    C, D         // 1, 1 << 10
)
//如果 iota ⾃增被打断,须显式恢复。
const (
    A = iota // 0
    B // 1
    C = "c" // c
    D // c,与上⼀⾏相同。
    E = iota // 4,显式恢复。注意计数包含了 C、 D 两⾏。
    F // 5
)

5、指针

Go语言支持指针类型 *T ,指针的指针 **T ,以及包含包名前缀的 *package.T

  • 操作符 "&" 取变量地址, "*" 透过指针访问目标对象。
  • 默认值 nil,没有 NULL 常量。
  • 不⽀持指针运算,不⽀持 "->" 运算符,直接⽤ "." 访问目标成员。

指针声明

var ip *int         //声明一个int值的指针变量
var sp *string        //生成string值的指针变量
var str="hello"
sp:= &str            //:=定义指针
var p **int            //声明指针的指针

类型转换:go语言指针是不允许指针类型转换的。但是unsafe.Pointer可以变相实现运算

unsafe.Pointer类型用于表示任意类型的指针。有4个特殊的只能用于Pointer类型的操作:

1、 任意类型的指针可以转换为一个Pointer类型值

2、 一个Pointer类型值可以转换为任意类型的指针

3、 一个uintptr类型值可以转换为一个Pointer类型值

4、 一个Pointer类型值可以转换为一个uintptr类型值

func main() {
    d := struct {
    s string
    x int
}{"abc", 100}
    p := uintptr(unsafe.Pointer(&d)) // *struct -> Pointer -> uintptr
    p += unsafe.Offsetof(d.x)         // uintptr + offset
    p2 := unsafe.Pointer(p)         // uintptr -> Pointer
    px := (*int)(p2)                 // Pointer -> *int
    *px = 200                         // d.x = 200
    fmt.Printf("%#v\n", d)
}
//输出:
struct { s string; x int }{s:"abc", x:200}

注意: GC 把 uintptr 当成普通整数对象,它⽆法阻⽌ "关联" 对象被回收。

6、字符串

字符串是不可变的 值类型 ,内部用指针指向UTF-8字节数组。

Go 语言中,没有字符类型,字符类型是rune类型,rune是int32的别称。可使用 []byte() 获取字节,使用 []rune() 获取字符,可对中文进行转换。

  • 默认值是空字符串 ""。
  • ⽤索引号访问某字节,如 s[i]。
  • 不能⽤序号获取字节元素指针, &s[i] ⾮法。
  • 不可变类型,⽆法修改字节数组。
  • 字节数组尾部不包含 NULL。

(1)定义字符串

//“abc” 双引号定义字符串 ``  反引号定义非转义字符串,多行
str := `aaaa
            可以跨行`
str:="abc"

(2)+号连接字符串:,"+" 必须在上一行末尾,否则导致编译错误。连接是会产生新的字符串。

​ 当然还有函数连接,这个放到字符串专题总结。如fmt.Sprintf() 等

(3)单引号字符常量

​ 单引号字符常量表⽰ Unicode Code Point,⽀持 uFFFF、 U7FFFFFFF、 xFF 格式。对应 rune 类型, UCS-4。

func main() {
    fmt.Printf("%T\n", 'a')
    var c1, c2 rune = '\u6211', '们'
    println(c1 == '我', string(c2) == "\xe4\xbb\xac")
}
//输出:
int32 // rune 是 int32 的别名
true true

(4)修改字符串

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

7、自定义类型和类型别名

可将类型分为命名和未命名两⼤类。命名类型包括 bool、 int、 string 等,⽽ array、slice、 map 等和具体元素类型、⻓度等有关,属于未命名类型。

具有相同声明的未命名类型被视为同⼀类型。

  • 具有相同基类型的指针
  • 具有相同元素类型和⻓度的 array。
  • 具有相同元素类型的 slice。
  • 具有相同键值类型的 map。
  • 具有相同元素类型和传送⽅向的 channel。
  • 具有相同字段序列 (字段名、类型、标签、顺序) 的匿名 struct。
  • 签名相同 (参数和返回值,不包括参数名称) 的 function。
  • ⽅法集相同 (⽅法名、⽅法签名相同,和次序⽆关) 的 interface。

使用type关键字自定义类型:

//可⽤ type 在全局或函数内定义新类型。
func main() {
    type bigint int64
    var x bigint = 100
    println(x)
}

注意:新类型不是原类型的别名,除拥有相同数据存储结构外,它们之间没有任何关系,不会持有原类型任何信息。除⾮目标类型是未命名类型,否则必须显式转换。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Data Mining

Web Data Mining

Bing Liu / Springer / 2006-12-28 / USD 59.95

Web mining aims to discover useful information and knowledge from the Web hyperlink structure, page contents, and usage data. Although Web mining uses many conventional data mining techniques, it is n......一起来看看 《Web Data Mining》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换