GO 学习

GO

安装-vscode

  • 下载
    • 控制台 go version 查看是否安装成功
  • vscode 中使用
    • step1: 在控制台中输入以下命令
    go env -w GO111MODULE=on
    go env -w GOPROXY=https://goproxy.cn,direct
    
    • step2: vscode 中安装插件 go
    • step3: vscode 中按下 ctrl+shift+p 把七个依赖全部勾选后点击ok下载
      全选
      在这里插入图片描述
  • 使用
    • 在文件->打开文件夹打开我们的$GOPATH下的src目录 建工程写代码
    • 在终端中用go build xx和go run xx来运行代码 或者 VSCode的插件模块,搜索code running来安装插件

安装-idea

  • idea 下载
  • idea 安装 go 插件
    • 在 idea 的 plugin 的应用市场如果下载若失败则看下面方法
    • 在线插件 找到自己想要的插件,可以下载到本地然后再 idea 的 plugin 中选择从本地导入即可
  • 推荐插件
    • translation

基础知识

// 会把换行符转化为分号,以下是特例
func main { // 不会转化

}
func main // 错误的书写方法
{

}
var a = 1+2;
var a = 1 // 会转化
+2;
var a = 1+ // 不会转化
2;

  • go get golang.org/x/tools/cmd/goimports 自动删除\添加包

  • 程序导入了两个包,用括号把它们括起来写成列表形式, 而没有分开写成独立的import声明。两种形式都合法,列表形式习惯上用得多。包导入顺序并不重要;gofmt工具格式化时按照字母顺序对包名排序。

    import (
        "fmt"
        "os",
        "bufio"
    )
    fmt.Sprintf();
    fmt.Println(); // %t 布尔:true或false; %q 带双引号的字符串"abc"或带单引号的字符'c'; %T 变量类型
    input:=bufio.NewScanner(os.stdin);
    input.Scan(); // 每次调用都会读取一行
    input.Text();
    
  • 每个 Go 应用程序都包含一个名为 main 的包。main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)

info

  • 学习文档

  • 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。

  • 表达式(Expression)有值,而语句(Statement)不总有。

  • 自增语句i++给i加1;这和i += 1以及i = i + 1都是等价的。对应的还有i–给i减1。它们是语句,而不像C系的其它语言那样是表达式。所以j = i++非法,而且++和–都只能放在变量名后面,因此–i也非法。a = a++ // 这是不允许的,会出现编译错误

  • for 循环

for { // 无限循环
  // ...

}

// 不可重复声明变量
var a = 1;
var a int = 1;
a:=1;

intVal := 1
// 相当于
var intVal int = 1;

f := 'hi'
// 相当于
var f string = 'hi';

var (  // 这种因式分解关键字的写法一般用于声明全局变量
  a int
  b bool
)

//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"

// 如果你在定义变量 a 之前使用它,则会得到编译错误 undefined: a。声明了缺不使用也是不行的,但是全局变量是允许声明但不使用的

// iota 是编辑器可以修改的常量,每 const 出现时就会被初始化为 0,随着标识符数量增加而增加
const (
    i = iota
    j = iota
    x = iota
)
const xx = iota
const yy = iota
func main(){
    println(i, j, x, xx, yy) // 输出是 0 1 2 0 0
}

var b int = 5
var ptr1 *int = &b;
fmt.Println(*ptr1)//5
fmt.Println(ptr1)// b 的地址

var numbers [3]int
var numbers = [...]int{1, 2, 3, 4, 5}
numbers:=[5]int{1:2,2:19}

animals := [][]string{}
// 创建三一维数组,各数组长度不同
row1 := []string{"fish", "shark", "eel"}
row2 := []string{"bird"}
row3 := []string{"lizard", "salamander"}
// 使用 append() 函数将一维数组添加到二维数组中
animals = append(animals, row1)
animals = append(animals, row2)
animals = append(animals, row3)
  • 局部变量:在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。
  • 全局变量:在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用。有异议
  • 可通过花括号来控制变量的作用域
  • 在Go语言中,字符串类型是一个结构体,包含一个指向底层数据的指针和一个表示字符串长度的整数。在64位系统上,每个指针占用8字节,整数占用8字节。因此,一个字符串类型在64位系统上总共占用16字节的空间。对于给定的代码a = “hello”,虽然a是一个字符串类型的变量,但在赋值时,实际上是将一个指向字符串"hello"底层数据的指针赋值给了a。因此,unsafe.Sizeof(a)返回的是一个指针的大小,即8字节。因此,代码a = "hello"; unsafe.Sizeof(a)的运行结果是8。
  • &a; 将给出变量的实际地址。
  • Go 没有三目运算符,所以不支持 ?: 形式的条件判断。
  • Go 函数可以返回多个值
  • 未定义长度的数组(切片)只能传给不限制数组长度的函数,定义了长度的数组只能传给长度一样的函数。
  • select 语法 (不懂)
  • 对于底层数组容量是 k 的切片 slice[i:j] 来说新的切片 长度: j-i 容量: k-i
  • 在做函数调用时,slice 按引用传递,array 按值传递
  • 并发 (不懂)
// 结构体
type Person struct {
  name string,
  age int,
}
// one
Person{'hi', 10};
// two
Person{name:'hi', age:10};
// three
var p1 Person;
p1.name = 'hi';
// 切片和range
var slice1 []type = make([]type,10);
slice2:=make([]type,10,20);
len(slice2)//10
cap(slice2)//20
var slice3 []int // console.log(slice3) nil
append(slice3, 1,2,3) [1,2,3]
copy(slice1,slice2)
// range也可以用来枚举 Unicode 字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。
for i, v := range slice3 {
  fmt.Printf("2**%d = %d\n", i, v)
}
// map
var map1 = make(map[string]int, 10) // 创建一个初始容量为 10 的关键字为 string 类型,值为 int 类型的 map; 遍历 Map 时返回的键值对的顺序是不确定的
map2 = map([string]string) { // := 写错啦
  name: '张三',
  age: '10'
}
keyValue:=map2['name']
key,value:=map2['age']
map2['age'] = '20'
delete map2['name']
for key:=range map2 {

}
// 数据类型转化, go 中没有隐式转化
value := float64(12)

value, err := strconv.Atoi('123')
value, err := strconv.Itoa(123)

value, err := strconv.ParseFloat('12', 64)
value, err := strconv.FormatFloat(12.345, 'f', 2, 64)
// 接口 不熟悉
type If interface {
  run() string
}
type Person struct {
  name string
}
func (p Person) run() string {
  //
  return p.name
}

var p If = Person{'张三'}
p.run() // 张三
// 通道
ch := make(chan int);
value,ok:=<-ch // 当收不到数据的时候 ok 就变成了 false,
close(ch) // 关闭通道
ch2 := make(chan int, 100)
// 如果通道不带缓冲,发送方会阻塞直到接收方从通道中接收了值。如果通道带缓冲,发送方则会阻塞直到发送的值被拷贝到缓冲区内;如果缓冲区已满,则意味着需要等待直到某个接收方获取到一个值。接收方在有值可以接收之前会一直阻塞。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值