Go基础(1)

116 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

前言

Go语言目前也是越来越流行的趋势。不管是从学习别的语言优势的角度,还是从把握住未来趋势的角度,我们都应该去学习一下Go。我们是软件开发程序员,而不是某一种语言的程序员,所以我们不应该给自己设限。

1.值传递和引用传递

Go中所有参数传递都是值传递,拷贝的都是一个副本。但是,分为引用类型非引用类型

非引用类型:int、string、float、bool、数组和struct

特点:值类型变量声明后,变量存的是值,内存通常在栈上分配,栈在函数调用后被释放

引用类型:指针、slice、map、channel、接口、函数等

特点:变量存放的是一个内存地址值,这个地址值指向的空间存的才是最终的值。内存通常在堆中分配,当没有任务变量引用这个地址时,该地址对应的数据空间就变为一个垃圾,通过GC回收

2.安装

//1.官网下载
https://go.dev/dl/

//2.开启go module
go env -w GO111MODULE=on

//3.配置代理
go env -w GOPROXY=https://goproxy.cn,direct

3.变量

// 1.var 变量名 变量类型 = 变量值
var name string = "韩非子"
var age int = 22
//自动推导
var name = "韩非子"
var age = 22

//一次定义多个变量
var(
  name string
  age int
)


//2.短变量声明并初始化-语法糖,函数外无法使用
name := "韩非子" <=> var name string = "韩非子"
age := 22       <=> var age int = 22


//3.获取变量内存地址 &变量名
fmt.Printf("变量内存地址:%T", &name)


//4.变量就换
a := 100
b := 200
a,b = b,a


/*
  5.匿名变量
  匿名变量是一个下划线"_",被称为空白标识符。它可以接收值(任何类型都可以),单任何赋值给这个
  标识符的值都会被抛弃,因此这些值不能在后续的代码中使用。匿名变量不占用内存地址,不会分配内存。
*/
func test() (int, int) {
  return 100, 200
}

a, _ := test()


/*
  6.变量分类
  局部变量:定义在函数内,它们的作用域只在函数体内,函数的参数和返回值都属于局部变量
  
  全局变量:定义在函数外,全局变量只需要在一个源文件内定义,就可以在所有源文件中使用,当然,不包含这个
  全局变量的源文件需要使用"import"关键字引入全局变量所在的原文件之后才能使用这个全局变量
  全局变量必须以var关键字开头,如果想要在外部包中使用全局变量的首字母必须大写
*/

4.常量

//常量中数据类型只可以使布尔型、数字型(整数、浮点数和复数)和字符串型
const URL string = "www.baidu.com" //显式定义
const URL = "www.baidu.com" //隐式定义

//一次定义多个常量
const A,B,C = "1",2,false

//iota,特殊常量,可以认为是一个可以被编译器修改的常量。iota是go语言的常量计数器
const(
  a = iota //0
  b        //1
  c        //2
  d="haha" //"haha"
  e        //"haha"
  f = 100  //100
  g        //100
  h = iota //7
  i        //8
)

5.数据类型

  • 布尔类型(bool)

    • true
    • false
  • 整形(int)

    • uint8无符号8为整形(0 - 255)别名:byte
    • uint16无符号16位整数(0 - 65535)
    • uint32无符号32位整数(0 - 4294967295)
    • uint64无符号64位整数(0 - 18446744073709551615)
    • int8有符号8位整数(-128 - 127)
    • int16有符号16位整数(-32768 - 32767)
    • int32有符号32位整数(-2147483648 - 2147483647)别名:rune
    • int64有符号64位整数(-9223372036854775808 - 9223372036854775807)
  • 浮点型(float)

    • float32 IEEE-754 32位浮点型数
    • float64 IEEE-754 64位浮点型数
    • complex64 32位实数和虚数
    • complex128 64位实数和虚数
  • 字符串型(string)

//数据类型转换
a := 3
b := float64(a)

c := 5.0
d := int(c)

6.输入/输出

var a int
var b float64

fmt.Scan(&a, &b)
fmt.Println("a:", a, "b:", b)

7.if

a := 1

if a==1 {
  fmt.Println(1)
}

8.switch

//go中switch默认带break,如果识别成功,就不会向下执行
a := 1

switch a {
case 1:
  fmt.Println(1)
case 2:
  fmt.Println(2)
case 3:
  fmt.Println(3)
default:
  fmt.Println("不知道")
}

//fallthrough穿透,如果执行成功也会在执行下面条件的内容(不管下面条件是否匹配都会执行),break可以终止
a := 1

switch a {
case 1:
  fmt.Println(1)
  fallthrough
case 2:
  fmt.Println(2)
case 3:
  fmt.Println(3)
default:
  fmt.Println("不知道")
}

9.循环

//打印1-10
for i := 0; i < 10; i++ {
  fmt.Println(i)
}

//死循环
for {
  fmt.Println(1)
}

for true {
  fmt.Println(1)
}

10.遍历字符串

str := "hanfz"

//leng()获取字符串长度
for i := 0; i < len(str); i++ {
  fmt.Printf("%c", str[i])
}

//for range循环,遍历数组、切片...
for i, v := range str {
  fmt.Printf("下标:%d, 值:%c", i, v)
}

11.string

//获取string长度
fmt.Println(len("HelloWorld")) //10

//byte数组转string
fmt.Println(string([]byte{65, 66, 67})) //ABC

//截取string
str := "HelloWorld"
fmt.Println(str[0])   //获取相应位置 72
fmt.Println(str[2:5]) //包含头不包含尾 llo
fmt.Println(str[3:])  //指定位置到结尾 loWorld
fmt.Println(str[:5])  //从头开始到指定位置减一 Hello

//strings操作
strings.Index()     //获取出现的位置
strings.HasPrefix() //判断是否是前缀
strings.HasSuffix() //判断是否是后缀
strings.Contains()  //判断是否包含
strings.Split()     //按找字符进行截取为数组
strings.ToUpper()   //转大写
strings.ToLower()   //转小写

12.数组

//数组定义,默认值为对应的“零”值
var arr [3]int

//定义并初始化
var arr = [3]int {1,2,3}
var arr = [5]int {1,2,3} // 剩下的两个数是0

//定义并初始化-省略数组长度
var arr = [...]int {1,2,3} // 有几个值,数组长度就是几

//定义并初始化-指定索引值初始化
var arr = [...]int {1: 1, 3: 3} // 有四个值,最大索引为3,索引1、3有值,其他为默认“零”值