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())
}

你可能还喜欢下面这些文章

Go语言的 make 和 new

new 和 make 是两个内置函数,主要用来创建并分配类型的内存。在我们定义变量的时候,可能会觉得有点迷惑,不知道应该使用哪个函数来声明变量,其实他们的规则很简单,new 只分配内存,make 只能用于 slice、map 和 channel 的初始化。下面我们就来具体介绍一下new在Go语言中,new 函数描述如下:从上面的代码可以看出,new 函数只接受一个参数,这个参数是一个类型,并且返回一个指向该类型内存地址的指针。同时 new 函数会把分配的内存置为零,也就是类型的零值。【示例】使用 new 函数为变量分配内存空间。当然,new 函数不仅仅能够为系统默认的数据类型,分配空间,自定义

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

这是我的C++学习笔记第一篇,同所有的程序语言学习路径一样,首先学习的是变量和数据类型。我的学习路径如下:1. 变量和数据类型2. 流程控制3. 函数声明和调用4. 面向对象5. 标准库这一章,学习的是变量和数据类型,需要了解的有:了解这些,对于变量基本就够了。Hello world在开始之前,先写一个hello world来熟悉一下程序的主要结构以及如何打印一个变量。iostream提供标准输入输出的头文件,程序以main函数问入口,std为标准库的命名空间,“<<” 为输出操作符,std::cout为标准输出,std::endl为结束符,表示将等待输出的内容从内存传送到标准输出

shell 变量的定义

shell可以自定义变量,这为shell的编写带来很多方便定义变量定义变量时,变量名不加美元符号($),如:variableName="value"注意:变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样同时,变量名的命名须遵循如下规则。首个字符必须为字母(a-z,A-Z)。中间不能有空格,可以使用下划线(_)。不能使用标点符号。不能使用bash里的关键字(可用help命令查看保留关键字)。变量定义举例:myUrl="http://imhuchao.com/tag/bash"myNum=100使用变量使用一个定义过的变量,只要在变量名前面加美元符号($)即可,如:your_nam

Go入门:四、面向对象

这是我的Go学习笔记的第四篇,面向对象!现代语言几乎都会面向对象进行了支持!当然,Go也具备面向对象的特性!我的语言学习过程一般分为下面几个:1. 变量和数据类型2. 流程控制方法3. 函数声明和调用4. 面向对象5. 语言特性6. 标准库Go语言中的面向对象有点特殊。在Go语言里面,没有显式的class、extends等面向对象语言经常使用的关键词,但是却有面向对象的特性。看看Go怎么实现的把!创建一个类按照我的理解,类实际上就是某种模板,这个模板里面含有有限多个属性和方法。在Go里面,定义这个模板的语法使用type来实现!比如单个int类型可以构成一个类(没错,你甚至可以在int数据类型上

Go入门:六、常用标准库

这是我的Go学习的第六篇笔记,也是Go入门的最后一篇笔记。在大多数语言中,了解了变量和数据类型,流程控制,函数,面向对象,再加上标准库,就可以用这门语言去写一些项目了。首先让我想想,在工作中通常会用语言频繁处理什么问题或者处理什么数据?最常见的应该是各种字符串操作,日期和时间,读写文件、socket等IO相关的操作!字符串处理 — StringsString提供了一组处理字符串的操作,常用的有:判断一个字符串是否在另一个字符串中分割字符串为[]string和组合[]string为一个字符串字符串替换...太多了,就不一一列举了,这里列出一些常用的字符串操作。字符串判断字符串分割与合并字符串转换

使用sublime+platuml高效画图

程序员难免要经常画流程图,状态图,时序图等。以前经常用 visio 画,经常为矩形画多大,摆放在哪等问题费脑筋。有时候修改文字后,为了较好的显示效果不得不再去修改图形。今天介绍的工具是如何使用 Sublime + PlantUML 的插件画流程图,状态图,时序图等。这是一种程序员看了就会爱上的画图方式:自然,高效。什么是 PlantUMLPlantUML 是一个画图脚本语言,用它可以快速地画出:时序图流程图用例图状态图组件图简单地讲,我们使用 visio 画图时需要一个一个图去画,但使用 PlantUML 只需要用文字表达出图的内容,然后就可以直接生成图片。看一个最简单的例子:软件安装这些软件

Go中使用json.Unmarshal interface{}之后的数据类型

有时候设计不好的情况下,一个json类型很难用固定的数据结构去表示,因此我们会用interface{}去表示它。在使用inteface的时候,需要了解json的数据类型对应的go的默认类型,使用才会不会出现疑惑,它们的类型关系对应如下JSONGobooleanbool数值float64字符串stringarray[]interface{}objectmapinterface{}nullnil了解他们默认的类型转换,使用时候就不会出问题了。

gcc/g++编译参数详解

编译步骤gcc 与 g++ 分别是 gnu 的 c & c++ 编译器。gcc/g++ 在执行编译工作的时候,总共需要4步:预处理,生成 .i 的文件将预处理后的文件转换成汇编语言, 生成文件 .s 有汇编变为目标代码(机器代码)生成 .o 的文件连接目标代码, 生成可执行程序 参数详解-x language filename参数含义为指定文件所使用的语言。根据约定,C语言的后缀名称为".c",而 C++ 的后缀名为".cpp"或".cc",但如果你的源代码后缀不约定的那几种,那么需要使用-x参数来指定文件所使用的语言。这个参数对他后面的文件名都起作用。 可以使用的参数吗有下面的这些:

python教程(一):变量和数据类型

python的基本数据类型有整型,浮点型,字符串,布尔,列表,元组,字典,集合。它们占用内存和定义方式如下表:类型占用内存如何定义整型(int)动态长度>=24字节a = 1浮点型(float)动态长度>=24字节a = 1.0字符串(string)动态长度,>=37字节,增加一个字符加1字节a = 'str'布尔(boolean)24字节a = True列表(list)动态长度,>=72字节a = []元组(tupe)动态长度,>=56字节a = ()集合(set)动态长度,>=232字节a = set([])占用的内存通过sys.getsizeof()获

从PHP到Go的程序员需要注意的一些事项

PHP转Go的程序员很多,使用Go重写Web应用,代价不高,并且所带来性能的提升很明显,因此很多PHP程序员正在转Go。PHP是一个弱类型,解释型的语言,Go是一个强类型,编译型语言,两者的差别很大。如果长期使用PHP,使用Go的时候,一些惯性思维会带来不太好的效果。这里总结一些从PHP转到Go需要注意的点。警惕内存越界访问一个数组,在php中,如果a是一个空数组,直接访问a会出现警告,但程序还能继续运行,而在Go中,由于访问一个不存在的地址,程序会直接崩溃。因此Go中需要时刻警惕内存越界。在访问数组下标的时候,如果不能确认需要访问数据一定存在,那么一定要使用len判断数组长度,需要访问的下标

赞赏

微信赞赏支付宝赞赏

发表回复

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