Go入门:一、变量和数据类型

这是学习Go语言的第一篇笔记,主要学习的是变量和基本数据类型。如果您也在开始学习Go语言,那么这篇笔记一定能帮助您学习的更快!

我的语言学习过程一般分为下面几个:

1. 变量和数据类型
2. 流程控制方法
3. 函数声明和调用
4. 面向对象
5. 语言特性
6. 标准库

变量声明

Go语言的变量声明有三种

第一种,var identifier type

// 先声明后赋值
var identifier type
identifier = value
// 声明并且赋值
var identifier type = value

开始实战一下!比如声明一个int类型变量

var i int
i = 1
// 或者
var i int = 1

第二种,var identifier = value

第二种不显式声明类型直接赋值。Go语言可以自动推导变量类型。比如

var i = 1
var j = 'str'

第三种,identifier := value

第三种是用来声明一个新的变量,好处就是用这个可以避免覆盖前面有值的变量,保证这个变量一定是一个新的变量。

比如 i:=1。关于这种声明方式,如果之前已经声明过的变量,再次使用将会编译错误。比如

var i
i := 1

这种编译的时候会报错。

写一个完整的Go程序!

package main
import "fmt"
func main() {
     i:=1
     fmt.Println(i)
}

疑问,为什么变量声明要把类型放在变量后面呢

数据类型

Go是一种强类型的语言,不同的数据选择不同的类型能够有效利用内存!

字符串型: string
字节类型: byte(uint8)
数字类型: int uint float32 float64 complex64 complex64 uint8 uint16 uint32 uint64 int8 int16 int32 int64 rune(int32) uintptr
布尔类型: bool
派生类型: 指针类型(Pointer) 数组类型 结构体类型 Channel类型 函数类型 切片类型 接口类型(Interface) Map类型

字符串类型,字节类型,数字类型,布尔类型构成了Go语言的基础类型。这也是大多数语言的基础类型。

挑几个重点数据类型做笔记!

字符串

字符串是一个非常常见的数据类型,几乎所有的语言都有这个数据类型。在Go语言中,字符串和数组类似,但是它是一个不可改变的数组!

概念:字符串是不可改变的字节序列!意味着字符串不可修改

// 定义一个字符串
var str string = "hello, 这是一个字符串"
fmt.Println(str) // 输出 "hello, 这是一个字符串"
fmt.Println(str[0]) // 输出104。这是h的ascii值

指针类型

概念:指针变量存储的是一个变量的内存地址!只能把地址赋值给这种变量

比如定义一个int型的变量,var i int = 1,那么可以定义一个int类型的指针来指向i的地址

// 声明一个指针变量
var ptr *int
var i int = 1 // &是取地址运算符,把i的地址赋值给
ptr = &i
fmt.Printf("i=%d, ptri=%x, prti value=%d", i, ptri, *ptri)

&为取地址运算,*为取地址中的值运算

常量

和一般语言一致,常量是在运行时不可修改的量。常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

声明一个常量

const identifier [type] = value

type可以省略,让编译器自动推导

数组(定长数组)

数组实际上就是一堆同类型数据的集合,在内存中的位置也是连续的。定义一堆同类型的变量用数组再合适不过啦!

// 声明一个长度为10的int型数组
var i [10] int
// 声明一个长度为10的float32型数组
var j [10] float32

上面仅仅是声明了一个数组,并未赋值,因此直接访问会全部是0(数字类型的没有初始化总是0)。要赋值也很简单,直接 i[index] = value这种方式就可以赋值啦。

创建一个一维数组

// 1. 初始化一个长度为5的int类型数组
var i = [5] int {1,2,3,4,5}
// 2. 不写长度,让编译器自己算
var i = [...] int {1,2,3,4,5,6}

创建一个多维数组

var value [SIZE1][SIZE2]...[SIZEN] identifier

比如创建一个int类型的二维数组

var i [2][3] int {{1,2,3}, {2,3,4}}

切片(变长数组)

数组的长度一旦声明就不可变,但是很多场景下需要让数组的长度随着程序的运行动态变化。因此Go提供了一个可变长度的数组,称为切片。

概念:切片是可变的数据类型 (联系一下字符串的不可变性)

var identifier []type
// 还可以使用make来初始化一个切片
var slice []type = make([]type, len) 
// 或者简写为
slice := make([]type, len)

实际上,这就定义了一个切片了。Go为切片定义了一系列能够修改数组的操作!

// 定义一个切片
s := []int {1,2,3,4}
// 截取切片中的一段,区间为左闭右开
s = s[startIndex:endIndex]
// 截取从某个位置开始到最后的区间
s = s[startIndex:]
// 截取从开始到某个位置结束
s = s[:endIndex]
// 追加
s = append(s, 5)
// 追加多个值
s = append(s, 5,6,7)

截取切片中的一段直接引用原数组,没有开辟新的内存,非常高效!在切片上追加一个新的值,只要切片容量足够就不会开辟新的内存空间!

Map(集合/索引数组/关联数组)

Map表示无序键值对集合。在其他语言中,通常也能看到这种身影,称呼可能有索引数组,字典等。不管称呼怎样,内部实现几乎是一致的,即通过hash表来实现。

// 使用make创建map
变量名 := make(map[key类型]值类型)

实战演练一下!

cities := make(map[string]string)

cities["北京"] = "北京是中国的首都,也是我家所在的地方"
cities["江西"] = "江西是我的老家"
cities["湖北"] = "2020中国新冠肺炎最严重的一个城市"

fmt.Println(cities["北京"])
fmt.Println(cities["江西"])
fmt.Println(cities["湖北"])

Go语言为Map这种数据类型定义了一些操作,这些操作有:delete(删除操作)

// 删除操作
delete(Map变量名, key)
// 例如
delete(cities, "湖北")

还记得对于int,string等一些简单的类型我们可以用var i int, i = 1这种类似的方法去赋值,那么对于map这样可以吗?比如

var cities map[string]string
cities["beijing"] = "北京" // panic: assignment to entry in nil map

这样会导致panic异常。空map是不允许直接赋值的。这里我们需要使用make来为map分配内存之后才可以进行赋值。

以下内容是学习函数后记下的笔记,如果您看到这儿,建议学习函数之后再回来看。

变量作用域

Go语言变量作用域可分为:局部、全局。

全局变量

函数体外定义的变量为全部变量,在任何函数都可使用和被修改!

局部变量

函数内部定义的变量为局部变量,作用域只限于函数内!在函数体内,可以定义和全局变量一样的变量名,这是一个局部变量,并且在函数体内会被优先使用。

实战演练

package main
import "fmt"

// 定义全局变量
var sword string = "一把剑"
var kongfu string = "所有人都会功夫"
func main() {
    iSay()
    my := getSword()
    fmt.Printf("我拥有: %s\n", my)
    fmt.Printf("所有人都有: %s\n", sword)
}
func iSay() {
    fmt.Println(kongfu)
}
func getSword() string {
    // 定义局部变量
    sword := "倚天剑"
    return sword
}
// 输出
所有人都会功夫
我拥有: 倚天剑
所有人都有: 一把剑

以下内容是学习面向对象后记下的笔记,如果您看到这儿,建议看完面向对象之后再回来看。

Go Struct 复合数据类型

使用数组可以定义一组同数据类型的数据。不过如果要定义一本书,这本书有作者,标题,价格等信息,用单一类型显然就不能表示。这时候就需要使用符合数据类型。

Go语言中使用type来定义复合数据类型。

type 结构体类型 struct {
   成员1 类型1
   成员2 类型2
   ...
   成员n 类型n
}

比如上面说的定义一本书

type Book struct {
    name   string
    author string
    price  int
}
// 赋值
book := Book{name: "Go秘籍", author: "imhuchao", price: 0}
fmt.Println(book)
// 访问成员
fmt.Println(book.name)
// 给成员赋值
book.price = 99
fmt.Println(book.price)

Go Interface 接口

Go Interface也是一个数据类型,看看怎样定义一个接口!

// 定义一个接口
type 接口名 interface {
    接口方法 返回值
}
// 比如定义一个人类接口
type Human interface {
    say() string
}

任何类型,只要实现了这个接口里面的方法,就相当于实现了这个接口。

实战演练一下

package main

import "fmt"

type Human interface {
	say() string
}

type Man struct {
}

type Woman struct {
}

func (m Man) say() string {
	return "我是个男人"
}

func (w Woman) say() string {
	return "我是个女人"
}

func main() {

	var man Human
	var woman Human

	man = new(Man)
	woman = new(Woman)

	fmt.Println(man.say())
	fmt.Println(woman.say())
}

赞赏

微信赞赏支付宝赞赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注