go语言基础学习随笔<1>

、前言

1、go语言介绍

​        Go 即Golang,是Google 公司2009 年11 月正式对外公开的一门编程语言。Go 语言不仅拥有静态编译语言的安全和高性能,而且又达到了动态语言开发速度和易维护性。有人形容Go 语言:Go = C + Python , 说明Go 语言既有C 语言程序的运行速度,又能达到Python 语言的快速开发。

2、Go 环境win 环境搭建

1、下载安装Golang

        Go 官网下载地址:https://golang.org/dl/

        Go 官方镜像站(推荐):Downloads - The Go Programming Language

2、安装软件

​         1、双击下一步下一步进行安装;

        ​ 2、验证是否安装成功:go version;

3、查看Go环境

​        go env

说明:

​         Go1.11 版本之后无需手动配置环境变量,使用go mod 管理项目,也不需要非得把项目放到GOPATH 指定目录下,你可以在你磁盘的任何位置新建一个项目。

        Go1.13 以后可以彻底不要GOPATH 了。        

二、基本语法

1、变量、常量命名规则

        (1)、变量名由字母、数字、下划线组成,其中首个字符不能为数字;

        (2)、关键字和保留字不能用作变量名。

        (3)、变量需要声明后才能使用,同一作用域内不支持重复声明。

        (4)、Go 语言的变量声明后必须使用。

        (5)、变量的名字是区分大小写的如: age 和Age 是不同的变量。

        (6)、变量命名一般采用驼峰式,当遇到特有名词(缩写或简称,如DNS)的时候,特有名词根据是否私有全部大写或小写。

1.1、Go 语言代码风格

​        1、代码每一行结束后不用写分号( ;);

        2、运算符左右建议各加一个空格 var username string = "xiaobai";

        3、Go 语言程序员推荐使用驼峰式命名;

        4、强制的代码风格——左括号必须紧接着语句不换行;

        5、go fmt 主要用于格式化文档,让所有人的代码风格保持一致。

2、变量的声明

​        Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量若未指定初始值,则会被初始化成其类型的默认值,例如: 整型和浮点型变量的默认值为0。字符串变量的默认值为空字符串。布尔型变量默认为false。切片、函数、指针变量的默认为nil。

2.1、var 声明变量

​        var 变量名 类型 (= 表达式)

eg:    var name string = "zhangsan"

2.2、变量类型自动推导

​         var 变量名 (= 表达式)

eg:    var name = "zhangsan"

2.3、短变量声明法

​         变量名 := 表达式

注意:短变量只能用于声明局部变量,不能用于全局变量的声明

eg:    name := "zhangsan"

2.4、变量的批量声明

​         var identifier1, identifier2 type

// 1、批量声明同类型变量
var name, area string
name = "wang"
area = "上海"
fmt.Printf("name:%v  ;area:%v\n",name,area)
​
// 2、批量声明不同类型的变量
var (
   user string
   sex string
   age int
)
user = "wang"
sex = "man"
age = 20
fmt.Printf("user:%v-%T;sex:%v-%T;age:%v-%T\n",user,user,sex,sex,age,age)
​
// 3、批量声明不同类型的变量,并赋值
var (
   user2 = "wang"
   sex2 = "man"
   age2 = 20
)
user2 = "wang"
sex2 = "man"
age2 = 20
fmt.Printf("user:%v-%T;sex:%v-%T;age:%v-%T\n",user2,user2,sex2,sex2,age2,age2)

2.5、匿名变量

​        在使用多重赋值时,如果想要忽略某个值,可以使用匿名变量(anonymous variable)。匿名变量用一个下划线_表示,例如:

func getInfo() (int, string) {
    return 10, "张三"
}
​
func main() {
    _, username := getInfo()
    fmt.Println(username)
}

        匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。

注意事项:

        1、函数外的每个语句都必须以关键字开始(var、const、func 等);

        2、:= 不能使用在函数外;

        3、_ 多用于占位,表示忽略值。

3、常量

        相对于变量,常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。常量的声明和变量声明非常类似,只是把var 换成了const,常量在定义的时候必须赋值

3.1、使用const 定义常量

// 1、常量定义
const pi = 3.1415926
const name = "wang"
​
// 2、批量多个常量
const (
   user = "wang"
   sex = "man"
)
​
// 3、const同时声明多个常量时,如果省略了值则表示和上面一行的值相同
const (
   n1 = 100
   n2
   n3
)

3.2、iota

​        iota 是golang 语言的常量计数器,只能在常量的表达式中使用

​        iota 在const 关键字出现时将被重置为0(const 内部的第一行之前);

​        const 中每新增一行常量声明将使iota 计数一次(iota 可理解为const 语句块中的行索引)。

3.2.1、iota 只能在常量的表达式中使用。

fmt.Println(iota)
编译错误: undefined: iota

3.2.2、每次const 出现时,都会让iota 初始化为0。【自增长】

const a = iota // a=0
const (
    b = iota //b=0
    c //c=1
)

3.2.3、const iota 使用_跳过某些值

const (
    n1 = iota //0
    n2 //1
    _
    n4 //3
)

3.2.4、iota 声明中间插队

const (
    n1 = iota //0
    n2 = 100 //100
    n3 = iota //2
    n4 //3
)
const n5 = iota //0

3.2.4、多个iota 定义在一行

const (
    a, b = iota + 1, iota + 2 //1,2
    c, d //2,3
    e, f //3,4
)

4、数据类型介绍

        Go 语言中数据类型分为:基本数据类型和复合数据类型

        基本数据类型有:整型、浮点型、布尔型、字符串

        复合数据类型有:数组、切片、结构体、函数、map、通道(channel)、接口等。

4.1、整数

​        整型分为以下两个大类: 有符号整形按长度分为:int8、int16、int32、int64 对应的无符号整型:uint8、uint16、uint32、uint64

%b 二进制
%c 对应的 Unicode 码位所代表的字符
%d 十进制
%o 八进制
%O 八进制,带 0o 前缀
%q 使用 Go 语法安全转义的单引号字符文字。
%x 十六进制,af用小写字母
%X 十六进制,AF为大写字母
%U Unicode 格式:U+1234;与 "U+%04X" 相同
类型范围占用空间(字节)有无符号
int8(-128到127) -2^7 到2^7-11
int16(-32768 到32767) -2^15 到2^15-12
int32(-2147483648 到2147483647)4
int64(-9223372036854775808 到9223372036854775807)<br />-2^63 到2^63-18
uint8(0 到255) 0 到2^8-11
uint16(0 到65535) 0 到2^16-12
uint32(0 到4294967295) 0 到2^32-14
uint64(0 到18446744073709551615) 0 到2^64-18

关于字节: 字节也叫Byte,是计算机数据的基本存储单位。8bit(位)=1Byte(字节);1024Byte(字节)=1KB;1024KB=1MB 1024MB=1GB 1024GB=1TB 。

特殊整型

类型描述
uint32 位操作系统上就是uint32,64 位操作系统上就是uint64
int32 位操作系统上就是int32,64 位操作系统上就是int64
uintptr无符号整型,用于存放一个指针

注意:

​        在使用int 和uint 类型时,不能假定它是32 位或64 位的整型,而是考虑int 和uint可能在不同平台上的差异。

注意事项:

         实际项目中整数类型、切片、map 的元素数量等都可以用int 来表示。在涉及到二进制传输、为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用int 和uint。

int不同长度直接的转换:

package main
import (
    "fmt"
)
func main() {
    var num1 int8
    num1 = 127
    num2 := int32(num1)
    fmt.Printf("值:%v 类型%T", num2, num2) //值:127 类型int32
}

​        Go1.13 版本之后引入了数字字面量语法,这样便于开发者以二进制、八进制或十六进制浮点数的格式定义数字,例如:v := 0b00101101, 代表二进制的101101,相当于十进制的45。v := 0o377,代表八进制的377,相当于十进制的255。v := 0x1p-2,代表十六进制的1 除以2²,也就是0.25。而且还允许我们用_ 来分隔数字,比如说:v := 123_456 等于123456。我们可以借助fmt 函数来将一个整数以不同进制形式展示。

4.2、浮点型

​        Go 语言支持两种浮点型数:float32 和float64。

​        这两种浮点型数据格式遵循IEEE 754 标准:float32 的浮点数的最大范围约为3.4e38,可以使用常量定义:math.MaxFloat32。float64 的浮点数的最大范围约为1.8e308,可以使用一个常量定义:math.MaxFloat64。打印浮点数时,可以使用fmt 包配合动词%f,代码如下:

package main
import (
    "fmt"
    "math"
)
func main() {
    fmt.Printf("%v\n", math.Pi) //原样输出
    fmt.Printf("%f\n", math.Pi) //默认保留6 位小数
    fmt.Printf("%.2f\n", math.Pi) //保留2 位小数
}

Go 语言中浮点数64位系统中默认是float64

num := 1.1
fmt.Printf("值:%v--类型:%T", num, num) //值:1.1--类型:float64

4.2.1、float 精度丢失问题

​        几乎所有的编程语言都有精度丢失这个问题,这是典型的二进制浮点数精度损失问题,在定长条件下,二进制小数和十进制小数互转可能有精度丢失。

d := 1129.6
fmt.Println((d * 100)) //输出:112959.99999999999
var d float64 = 1129.6
fmt.Println((d * 100)) //输出:112959.99999999999
m1 := 8.2
m2 := 3.8
fmt.Println(m1 - m2) // 期望是4.4,结果打印出了4.399999999999999
使用第三方包来解决精度损失问题:
https://github.com/shopspring/decimal

4.2.2、科学计数法表示浮点类型

num8 := 5.1234e2 // ? 5.1234 * 10 的2 次方
num9 := 5.1234E2 // ? 5.1234 * 10 的2 次方shift+alt+向下的箭头
num10 := 5.1234E-2 // ? 5.1234 / 10 的2 次方0.051234
fmt.Println("num8=", num8, "num9=", num9, "num10=", num10)

4.3、布尔值

​        Go 语言中以bool 类型声明布尔型数据,布尔型数据只有true(真)和false(假)两个值。

注意:

  1. 布尔类型变量的默认值为false。

  2. Go 语言中不允许将整型强制转换为布尔型.

  3. 布尔型无法参与数值运算,也无法与其他类型进行转换。

package main
import (
    "fmt"
    "unsafe"
)
func main() {
    var b = true
    fmt.Println(b, "占用字节:", unsafe.Sizeof(b))
}

4.4、字符串

​        Go 语言中的字符串以原生数据类型出现,使用字符串就像使用其他原生数据类型(int、bool、float32、float64 等)一样。Go 语言里的字符串的内部实现使用UTF-8 编码。字符串的值为双引号(")中的内容,可以在Go 语言的源码中直接添加非ASCII 码字符,例如:s1 := "hello";s2 := "你好"

字符串转义符

         Go 语言的字符串常见转义符包含回车、换行、单双引号、制表符等,如下表所示。

转义符含义
\r回车符(返回行首
\n换行符(直接跳到下一行的同列位置)
\t制表符
\'单引号
\"双引号
\\反斜杠

举个例子,我们要打印一个Windows 平台下的一个文件路径:

package main
import (
"fmt"
)
func main() {
    fmt.Println("str := \"d:\\Code\\demo\\go.exe\"")
}

4.4.1、多行字符串

​        Go 语言中要定义一个多行字符串时,就必须使用反引号字符(tab键上的`)

s1 := `第一行
第二行
第三行
`
fmt.Println(s1)

​        反引号间换行将被作为字符串中的换行,但是所有的转义字符均无效,文本将会原样输出。

4.4.2、字符串的常用操作

方法介绍
len(str)求长度(字节)
+或fmt.Sprintf拼接字符串
strings.Split分割
strings.contains判断是否包含
strings.HasPrefix,strings.HasSuffix前缀/后缀判断
strings.Index(),strings.LastIndex()子串出现的位置,查找不到返回-1
strings.Join(a[]string, sep string) join操作把切片组合成字符串
// len(str)求字符串的长度
var str = "this is str"
fmt.Println(len(str))
​
// 字符串拼接
var str1 = "你好"
var str2 = "golang"
fmt.Println(str1 + str2)
var str3 = fmt.Sprintf("%v %v", str1, str2)
fmt.Println(str3)
// 字符串分割
var str = "123-456-789"
var arr = strings.Split(str, "-")
fmt.Println(arr)
// 字符串判断是否包含
var str = "this is golang"
var flag = strings.Contains(str, "golang")
fmt.Println(flag)
// 字符串判断首字符、尾字母是否包含指定字符
var str = "this is golang"
var flag = strings.HasPrefix(str, "this")
fmt.Println(flag)
var str = "this is golang"
var flag = strings.HasSuffix(str, "go")
fmt.Println(flag)
// 判断字符串出现的位置
var str = "this is golang"
var index = strings.Index(str, "is") //从前往后
fmt.Println(index)
var str = "this is golang"
var index = strings.LastIndex(str, "is") //从后网前
fmt.Println(index)
// Join 拼接字符串
var str = "123-456-789"
var arr = strings.Split(str, "-")
var str2 = strings.Join(arr, "*")
fmt.Println(str2)

4.4.3、修改字符串

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

func changeString() {
    s1 := "big"
    // 强制类型转换
    byteS1 := []byte(s1)
    byteS1[0] = 'p'
    fmt.Println(string(byteS1))
    s2 := "白萝卜"
    runeS2 := []rune(s2)
    runeS2[0] = '红'
    fmt.Println(string(runeS2))
}

4.5、byte 和rune 类型

         组成每个字符串的元素叫做“字符”,可以通过遍历字符串元素获得字符。字符用单引号(’)包裹起来,如:

package main
import "fmt"
func main() {
    a := 'a'
    b := '0'
    //当我们直接输出byte(字符)的时候输出的是这个字符对应的ASCII码值
    fmt.Println(a)
    fmt.Println(b)
    //如果我们要输出这个字符,需要格式化输出
    fmt.Printf("%c--%c", a, b) //%c 相应Unicode 码点所表示的字符
}

        字节(byte):是计算机中数据处理的基本单位,习惯上用大写B来表示,1B(byte,字节)= 8bit(位)。

        字符:是指计算机中使用的字母、数字、字和符号。

        utf-8:一个汉子占用3 个字节一个字母占用一个字节

a := "m"
fmt.Println(len(a)) //1
b := "张"
fmt.Println(len(b)) //3

4.5.1、Go语言的字符有以下两种:

​ (1)、uint8 类型,或者叫byte 型,代表了ASCII 码的一个字符。

​ (2)、rune 类型,代表一个UTF-8 字符。当需要处理中文、日文或者其他复合字符时,则需要用到rune 类型。rune 类型实际是一个int32Go 使用了特殊的rune 类型来处理Unicode,让基于Unicode 的文本处理更为方便,也可以使用byte 型进行默认字符串处理,性能和扩展性都有照顾。

// 遍历字符串
package main
import "fmt"
func main() {
    s := "hello 张三"
    for i := 0; i < len(s); i++ { //byte
        fmt.Printf("%v(%c) ", s[i], s[i])
    }
    fmt.Println()
    for _, r := range s { //rune
        fmt.Printf("%v(%c) ", r, r)
    }
    fmt.Println()
}

输出:

        104(h) 101(e) 108(l) 108(l) 111(o) 32( ) 229(å) 188(¼) 160( ) 228(ä) 184(¸) 137()

        104(h) 101(e) 108(l) 108(l) 111(o) 32( ) 24352(张) 19977(三)

        因为UTF8 编码下一个中文汉字由3 个字节组成,所以我们不能简单的按照字节去遍历一个包含中文的字符串,否则就会出现上面输出中第一行的结果。字符串底层是一个byte 数组,所以可以和[]byte 类型相互转换。字符串是不能修改的字符串是由byte 字节组成,所以字符串的长度是byte 字节的长度。rune 类型用来表示utf8 字符,一个rune 字符由一个或多个byte 组成。

c3 := "营"
c4 := '营'
fmt.Printf("C3 的类型%T--C4 的类型%T", c3, c4) //C3 的类型string--C4 的类型int32

4.6、GoLang 中基本数据类型之间的转换

4.6.1、关于golang 中的数据类型转换

​        Go 语言中只有强制类型转换,没有隐式类型转换。.

4.6.2、数值类型之间的相互转换

​        数值类型包括:整形和浮点型

package main
import "fmt"
func main() {
    var a int8 = 20
    var b int16 = 40
    var c = int16(a) + b //要转换成相同类型才能运行
    fmt.Printf("值:%v--类型%T", c, c) //值:60--类型int16
}
package main
import "fmt"
func main() {
    var a float32 = 3.2
    var b int16 = 6
    var c = a + float32(b)
    fmt.Printf("值:%v--类型%T", c, c) //值:9.2--类型float32
}

​        转换的时候建议从低位转成高位,高位转成低位的时,如果转换不成功就会溢出,和我们想的结果不一样,比如:

package main
func main() {
    var a int16 = 129
    var b = int8(a) // 范围-128 到127
    println("b=", b) //b= -127 //错误
}

         比如,使用math 包的Sqrt()函数,该函数接收的是float64 类型的参数,而变量a 和b 都是int 类型的,这个时候就需要将a 和b 强制类型转换为float64 类型。

var a, b = 3, 4
var c int
// math.Sqrt()接收的参数是float64 类型,需要强制转换
c = int(math.Sqrt(float64(a*a + b*b)))
fmt.Println(c)

4.6.3、其他类型转换成String 类型

1、sprintf 把其他类型转换成string 类型

        注意:sprintf 使用中需要注意转换的格式int 为%d;float 为%f;bool 为%t;byte 为%c;

2、使用strconv 包里面的几种转换方法进行转换

package main
import (
	"fmt"
	"strconv"
)
func main() {
	//1、int 转换成string
	var num1 int = 20
	s1 := strconv.Itoa(num1)
	fmt.Printf("str type %T ,strs=%v \n", s1, s1)
	// 2、float 转string
	var num2 float64 = 20.113123
	strs = fmt.Sprintf("%d", i)
	fmt.Printf("str type %T ,strs=%v \n", strs, strs)
	strs = fmt.Sprintf("%f", f)
	fmt.Printf("str type %T ,strs=%v \n", strs, strs)
	strs = fmt.Sprintf("%t", t)
	fmt.Printf("str type %T ,strs=%v \n", strs, strs)
	strs = fmt.Sprintf("%c", b)
	fmt.Printf("str type %T ,strs=%v \n", strs, strs)

	/*
		参数1:要转换的值
		参数2:格式化类型
		'f'(-ddd.dddd)、
		'b'(-ddddp±ddd,指数为二进制)、
		'e'(-d.dddde±dd,十进制指数)、
		'E'(-d.ddddE±dd,十进制指数)、
		'g'(指数很大时用'e'格式,否则'f'格式)、
		'G'(指数很大时用'E'格式,否则'f'格式)。
		参数3: 保留的小数点-1(不对小数点格式化)
		参数4:格式化的类型
	*/
	s2 := strconv.FormatFloat(num2, 'f', 2, 64)
	fmt.Printf("str type %T ,strs=%v \n", s2, s2)
	// 3、bool 转string
	s3 := strconv.FormatBool(true)
	fmt.Printf("str type %T ,strs=%v \n", s3, s3)
	//4、int64 转string
	var num3 int64 = 20
	/*
		第二个参数为进制
	*/
	s4 := strconv.FormatInt(num3, 10)
	fmt.Printf("类型%T ,strs=%v \n", s4, s4)
}

4.6.4、String 类型转换成数值类型

1、string 类型转换成int 类型

var s = "1234"
i64, _ := strconv.ParseInt(s, 10, 64)
fmt.Printf("值:%v 类型:%T", i64, i64)

2、string 类型转换成float 类型

str := "3.1415926535"
v1, _ := strconv.ParseFloat(str, 32)
v2, _ := strconv.ParseFloat(str, 64)
fmt.Printf("值:%v 类型:%T\n", v1, v1)
fmt.Printf("值:%v 类型:%T", v2, v2)

3、string 类型转换成bool 类型(意义不大)

b, _ := strconv.ParseBool("true") // string 转bool
fmt.Printf("值:%v 类型:%T", b, b)

4、string 转字符

s := "hello 张三"
for _, r := range s { //rune
	fmt.Printf("%v(%c) ", r, r)
}
fmt.Println()

4.6.5、数值类型没法和bool 类型进行转换

​        注意:在go 语言中数值类型没法直接转换成bool 类型bool 类型也没法直接转换成数值类型

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值