Go语言学习
[TOC]
Day 01 基础学习
basic
brew install go
go version
go env
vscode 编辑器
go install ..(tools)
package main
import "fmt"
func Hello() string{
return "hello world 2"
}
func swap(x, y string) (string, string) {
return y, x
}
func main(){
fmt.Println(Hello())
}
package xxx 指明package,程序从 main 包开始运行。
import "fmt" 导入包
import (
"fmt"
"time"
)
func Hello() string{}
当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,相当于public对其他包可见,小写则为protected 只在当前包内部可见;
string 表示返回参数类型, 写在变量名之后
func swap(x, y string) (string, string) {...}
(x, y string) 相同函数命名缩略
swap函数可以返回任意数量的返回值
Go没有类,但是可以在结构体类型上定义方法,方法接收者出现在func 与方法名之间
func (iPhone IPhone) call(){...}
data type
bool: true/false 默认false
number: 默认0
uint8/16/32/64
int8/16/32/64
float32/64
complex64/128 64 位实数和虚数
byte 同 uint8
rune 同 int32
uint 32 或 64 位
int 与 uint 一样大小
uintptr 无符号整型,用于存放一个指针
string: UFT-8编码标识的unicode文本,单个字节连接起来的的字符序列,默认""
other
pointer
array
struct
channel
method 函数类型
slice 切片类型
interface 接口类型
map
var/const
package main
import "fmt"
//声明常量,使用关键之 const
//常量不能用 := 语法声明
const d = "d"
//声明枚举
const (
YES = 1
NO = 0
)
func main(){
//声明变量
var a0 string = "1"
var a = "1"
b := "1"
fmt.Println(a == a0)//true
fmt.Println(a == b)//true
//多变量声明
a1, a2, a3 := 1, 2, 3
fmt.Printf("%v %v %v\n", a1, a2, a3)//1,2,3
fmt.Println(d)//d
fmt.Println(YES)//1
}
numbers & slice & point
package main
import "fmt"
func main(){
//声明数组
//对单引号和双引号敏感,string只支持双引号
numbers := [...]int{1, 2}
tests := [2]int{1, 2}
fmt.Println(tests[0])//1
for index := 0; index < 2; index++ {
fmt.Println(tests[index])
fmt.Println(numbers[index])
}
//切片
//初始化 s := arr[:]
slices := numbers[:]
fmt.Println(len(slices))//2
//截取 s := arr[startIndex:endIndex]
slices0 := numbers[0:1]
fmt.Println(len(slices0))//1
//空切片
var slices1 []int
fmt.Println(slices1)//[]
fmt.Println(slices1 == nil)//true
fmt.Println(len(slices1))//0
//pointer &取址符
//声明实际变量
e := 10
fmt.Println(&e) //变量在内存中的地址 0xc000092030
//声明指针变量
var ip *int
fmt.Println(ip) //未赋值时为空指针 nil 同null
ip = &e
fmt.Println(ip)
fmt.Println(*ip) //使用指针访问值 10
fmt.Println(e == *(&e)) //true
}
struct & map
package main
import "fmt"
//定义struct
//为数据结构体,用于封装数据集合
type Structs struct{
id int
remark string
}
func main(){
//创建新的struct
structs := Structs{id:1, remark:"remark 1"}
//structs := Structs{1, "remark 1"}
fmt.Println(structs) //{1 remark 1}
fmt.Println(structs.id) //1
//使用pointer访问
structPointer := &structs
fmt.Println(structPointer.id)//1
//定义map
testMap := map[string]int{"1": 1, "2": 2, "3": 3}
fmt.Println(testMap) //map[1:1 2:2 3:3]
//打印map数据
for key := range testMap {
fmt.Println(testMap[key])
}
fmt.Println(len(testMap))//3
//删除map元素
delete(testMap, "1")
fmt.Println(len(testMap))//2
}
interface
package main
import "fmt"
// 定义接口
type PhoneInteface interface{
call()
}
// 定义相关结构体
type IPhone struct{
name string
}
// 实现接口方法
func (iPhone IPhone) call() {
fmt.Printf("I am %s, I can call you!\n",iPhone.name)
}
func main(){
//创建struct
iPhone := IPhone{name:"iphone"}
//调用方法
iPhone.call()//I am iphone, I can call you!
}
error
package main
import "fmt"
// 实现Error 接口
func Error(s string) string{
return "error msg:" + s
}
func main(){
var errorMsg = Error("test error")
fmt.Println(errorMsg)//error msg:test error
}
concurrency
import (
"fmt"
"time"
)
func printData(c chan int){
for value := range c {
fmt.Printf("value:")
fmt.Println(value)
}
}
func say(s string){
for index := 0; index < 5; index++ {
time.Sleep(10)
fmt.Printf("%v %s\n", index, s)
}
}
func sum(s []int, c chan int){
sum := 0
for _, value := range s {
sum+=value
}
c <- sum
}
func main(){
// go 关键字来开启 goroutin 即创建新的线程
// goroutine 是轻量级线程
// ch <- v 将 v 送入 channel ch。
// v := <-ch 从 ch 接收,并且赋值给 v。
go say("world")
say("hello")
s := []int{1,4,5,7,8,9}
// 创建通道, 是用来传递数据的一个数据结构。
// 默认情况下,通道是不带缓冲区。发送端发送数据,同时必须又接收端相应的接收数据
c := make(chan int)
//关闭通道close(c)
//只有发送者才能关闭 channel,而不是接收者
//channel 与文件不同;通常情况下无需关闭它
//只有在需要告诉接收者没有更多的数据的时候才有必要进行关闭,例如中断一个 `range`
go sum(s, c)
go sum(s[:4], c)
before, after := <-c, <-c
fmt.Println(before, after)//17 34
//定义带缓存的通道,可异步获取,直到缓冲区满才会阻塞,当缓冲区清空的时候接受阻塞。
channalTest := make(chan int,2)
go sum(s, channalTest)
go sum(s[:4], channalTest)
go printData(channalTest)
time.Sleep(1000)
fmt.Println("OVER")//OVER
}