golang基础
Go介绍并发支持,垃圾回收的编译型系统编程语言。 特点:
GOEXE=.exe // 形成可执行文件的后缀 GOPATH // 工作目录 GOPATH下约定俗成的目录: bin // 存放编译后生成的可执行文件 pkg // 存放编译后生成的包文件 src // 存放项目源码
go get // 获取远程包 (git或hg(如果是谷歌code上托管)) go run // 直接运行程序 go build // 编译,检查是否有编译错误 go fmt // 格式化源码 go install // 编译包文件并且编译整个程序 go test // 运行测试文件 go doc // 查看文档 godoc -http=:8080 // 查看文档 GO程序结构
mpathapp // 可执行文件存放位置 math.a // 包文件 基础知识hello.go package main import ( "fmt" ) func main () { fmt.Println("hello world") }
Go程序是通过 通过 // 当前程序的包名 package main // 导入其它的包 // import . "fmt" // 省略调用 import ( "fmt" "io" "os" "time" "strings" ) // 常量的定义 const PI = 3.141592653 // 全局变量的声明与赋值 var name = "zf" // 一般类型声明 type newType int // 结构的声明 type struc struct{} // 接口关键字和大括号不能有空格 // 接口的声明 type inter interface{} // 接口关键字和大括号不能有空格 // 由 main 函数作为程序入口点启动 func main () { fmt.Println("hello world!") } 如果导入包之后,未调用其中的函数或者类型将会报出编译错误.
当使用第三方包时,包名可能会非常接近或者相同,此时就可以使用别名来进行区别和调用 import std "fmt" // 别名 std.Println("hello world")
// 单行注释 /* 多行注释 */
Go语言中,使用大小写来决定该常量,变量,类型,接口,结构,或函数是否可以被外部包所调用:根据约定,函数名首字母小写即为 类型与变量基本类型
长度:1字节
根据运行平台可能为32或64位
从严格意义上讲
长度:4/8字节
长度:8/16字节
array、struct、string
slice、map、chan
interface
func 类型零值零值并不等于空值,而是当变量被声明为某种类型后的默认值。 通常情况下:
变量单个变量的声明与赋值 变量的声明格式: var a int // 变量声明 a = 10 // 变量赋值 var b int = 20 // 变量声明的同时赋值 var b = 1 // 变量声明与赋值,由系统推荐是那种类型 b := 10 // 函数中的变量声明与赋值的最简写法 var 是全局的变量 := 只能在函数中使用,局部变量 多个变量的声明与赋值 全局变量的声明可使用 var ( // 使用常规方式 aaa = "hello" // 使用并行方式以及类型推断 a,b = 1,2 // cc := 2 // 不可以省略 var ) func main () { // 多个变量的声明 var a,b,c,d int // 多个变量的赋值 a,d = 1,2,3,4 // 多个变量声明的同时赋值 var e,f,g,h int = 5,6,7,8 // 省略变量类型,由系统推断 var i,j,k,l = 9,10,11,12 // 多个变量声明与赋值的最简写法 i,m,n,o := 13,14,15,16 _,dd = 10,20 // 空白符号,省略该表达式赋值(应用函数返回值) } 类型转换
// 在相互兼容的两种类型之间转换 var a float32 = 1.1 b := int(a) // 表达式无法通过编译 var c bool = true d := int(c) package main import ( "fmt" ) func main () { var a float32 = 100.01 fmt.Println(a) // 100.01 b := int(a) fmt.Println(b) // 100 } 整型无法和布尔型兼容
var c int = 3 // d := string(c) d := strconv.Itoa(c) // 字符串 3 c,_ = strconv.Atoi(d) // int 3 现象: var a int = 65 string(a) fmt.Println(a) // A
常量
const ( _A = "A" _B _C = iota _D ) func main () { fmt.Println(_A,_B,_C,_D) // A A 2 3 } const ( a = "123" b = len(a) c ) func main () { fmt.Println(a,c) // 123,3 } 编译不通过: var ss = "123" const ( a = len(ss) b c ) func main () { fmt.Println(a,c) } 错误信息: # command-line-arguments .const.go:39: const initializer len(ss) is not a constant const ( a,"xixi" c ) func main () { fmt.Println(a,c) } 错误信息: # command-line-arguments .const.go:40: extra expression in const declaration 运算符Go中的运算符从左至右结合 优先级(从高到低)
fmt.Println(1 ^ 2) // 二元运算符 fmt.Println(^2) // 一元运算符 /* 6: 0110 11: 1101 ------------ & 0010 // 2 | 1111 // 15 ^ 1101 // 13 &^ 0100 // 4 6 -> 110 5 -> 101 4 -> 100 13 / 2 = 1 // 6 1101 */ 控制语句
Go虽然保留了指针,但与其他编程语言不同的是,在Go当中不支持指针运算以及
package main import ( "fmt" ) func main () { a := 1 var p *int = &a fmt.Println(p) // 0xc0420361d0 fmt.Println(*p) // 1 } 递增递减语句
func main () { a := 10 if a := 0; a > 0 { fmt.Println(a) } else if a == 0 { fmt.Println(0111) // 73 } fmt.Println(a) // 10 }
// 第一种形式 func main () { a := 1 for { a++ if a > 3 { break } fmt.Println(a) // 2,3 } fmt.Println(a) // 4 } // 第二种形式 func main () { a := 1 for a <= 3 { a++ fmt.Println(a) // 2,4 } fmt.Println(a) // 4 } // 第三种形式 func main () { a := 1 for i := 0; i < 3; i++ { a++ fmt.Println(a) // 2,4 } fmt.Println(a) // 4 }
func main () { a := 1 switch a { case 0: fmt.Println("a=0") case 1: fmt.Println("a=1") } fmt.Println(a) } func main () { a := 1 switch { case a >= 0: fmt.Println("a>=0") fallthrough case a >= 1: fmt.Println("a>=1") } fmt.Println(a) } func main () { switch a := 1; { case a >= 0: fmt.Println("a>=0") fallthrough case a >= 1: fmt.Println("a>=1") default: fmt.Println("none") } fmt.Println(a) // undefined: a //for,if,switch都具有块级作用域 }
func main () { LABEL: for { for i := 0; i < 10; i++ { if i > 2 { break LABEL } else { fmt.Println(i) } } } } func main () { LABEL: for i := 0; i < 10; i++ { for { fmt.Println(i) continue LABEL } } } 数组Array
创建数组 func main () { var a [2]string var b [1]int c := [2]int{11,12} d := [20]int{19: 1} e := [...]int{1,4,5} f := [...]int{0: 11,1: 22,2: 33} b[0] = 10 a[1] = "100" arr := [...]string{0: "xixi",1: "hhh"} fmt.Println(a,d,e,f) } p := new([10]int) p[1] = 2 fmt.Println(&p) // 取地址 fmt.Println(*p) // 取值 // 多维数组 a := [2][3]int{ {1,1,1},{2,2},} fmt.Println(a) 冒泡排序: func main () { a := [...]int{3,234,5} fmt.Println(a) num := len(a) for i := 0; i< num; i++ { for j := i+1; j < num; j++ { if a[i] < a[j] { temp := a[i] a[i] = a[j] a[j] = temp } } } fmt.Println(a) } 切片Slice
声明: // 声明方法: var s1 []int // 中括号中没有数字或`...` fmt.Println(s1) // [] reslice方法: 从数组中截取 a := [...]int{1,5,8,9} fmt.Println(a) s1 := a[5: len(a)] // 包含起始索引,不包含终止索引 // a[5 6 7 8 9] s2 := a[5: ] // 包含起始索引,不包含终止索引 // a[5 6 7 8 9] fmt.Println(s1,s2) make方法 (一般使用make创建) s1 := make([]int,10) // 10小块连续的内存,如果slice超过10,内存卡会继续申请,重新生成内存地址 s2 := make([]int,10) // cap不给定,是slice的最大长度 fmt.Println(len(s1),cap(s1),s1) // 3 10 [0 0 0] fmt.Println(len(s2),cap(s2),s2) // 10 10 [0 0 0 0 0 0 0 0 0 0] Reslice
Append
s1 := make([]int,6) fmt.Println("%pn",s1) s1 = append(s1,4) fmt.Println("%v %pn",s1) // [0 0 0 1 2 3 4] Copy nt{1,7} s2 := []int{8,9} copy(s1,s2) // copy(s1,s2[1: 2]) fmt.Println(s1,s2) // [8 9 3 4 5 6 7] [8 9] Map
Map初始化 var m map[int]string // m = map[int]string{} m = make(map[int]string) var m1 map[int]string = make(map[int]string) m2 := make(map[int]string) fmt.Println(m,m1) // map[] 删除和常用Map方法赋值 m2 := make(map[int]string) m2[1] = "OK" delete(m2,1) a := m2[1] fmt.Println(a) 迭代: for i,v := range slice { // slice[i] } for k,v := range map { // map[k] } 取Map中的key m := map[int]string{1: "A",2: "B",3: "C",4: "D"} s := make([]int,len(m)) i := 0 for k,_ := range m { s[i] = k i++ } sort.Ints(s) fmt.Println(s) Map中的 key-value互换: m1 := map[int]string{1: "A",3: "C"} m2 := make(map[string]int) // m2 := map[string]int{"A": 1,"B": 2,"C": 3} for k,v := range m1 { m2[v] = k } fmt.Println(m1) fmt.Println(m2) Function函数function Go 函数 不支持嵌套、重载和默认参数
定义函数使用关键字 func,且左大括号不能另起一行 闭包: func closure (x int) func (int) int { return func (y int) int { return x + y } }
defer使用: func main () { fmt.Println("a") defer fmt.Println("b") defer fmt.Println("c") // a,b for i := 0; i < 3; i++ { defer fmt.Println(i) // 2 1 0 } for i := 0; i < 3; i++ { defer func () { fmt.Println(i) // 3 3 3 }() } }
func main () { A() B() C() } func A () { fmt.Println("func A") } func B () { defer func () { if err := recover(); err != nil { fmt.Println("Recover") } }() panic("Panic in B") } func C () { fmt.Println("func C") } 结构struct
type person struct { name string age int } func main () { a := person{} a.name = "zf" a.age = 23 fmt.Println(a) // { 0} }
对初始化结构 type person struct { name string age int } func main () { a := &person{ // 调用结构使用地址符 // 字面值初始化 name: "zf",age: 24,} a.name = "pink" // a.name = "zf" // a.age = 23 fmt.Println(a) // { 0} // A(&a) A(a) B(a) fmt.Println(a) } func A (per *person) { per.age = 18 fmt.Println("A",per) } func B (per *person) { per.age = 20 fmt.Println("B",per) } 匿名结构: func main () { a := &struct { name string age int } { name: "tan",age: 19,} fmt.Println(a) } 外层结构: type person struct { name string age int contact struct { phone,city string } } func main () { b := person { name: "yellow",age: 18,} b.contact.phone = "123123" b.contact.city = "xiamen" fmt.Println(b) } 匿名字段: type p1 struct { string int } func main () { c := p1{"cyan",20} // 字段的类型严格按照结构声明的字段 fmt.Println(a,c) } 匿名函数和匿名字段在函数中使用的次数非常少,没有必要声明,才会使用到。 嵌入(继承)结构: type human struct { Sex int } type teacher struct { human name string age int } type student struct { human name string age int } func main () { // a := teacher{name: "cyan",age: 20,human{sex: 0}} a := teacher{name: "cyan",human: human{Sex: 0}} b := student{name: "pink",age: 22,human: human{Sex: 1}} a.name = "xixi" a.age = 23 // a.Sex = 100 a.human.Sex = 200 fmt.Println(a,b) } 方法method
type Test struct { name string } type Person struct { name string } func main () { t := Test{} t.Print() fmt.Println(t.name) p := Person{} p.Print() fmt.Println(p.name) } func (t *Test) Print() { t.name = "red" fmt.Println("Test") } func (p Person) Print() { fmt.Println("Person") } // 类型别名不会拥有底层类型所附带的方法 type TZ int func main () { var a TZ a.Print() (*TZ).Print(&a) } func (a *TZ) Print() { fmt.Println("TZ") } 方法不同调用方式 type A struct { name string } func main () { a := A{} a.Print() // (*TZ).Print(&a) } func (a *A) Print() { a.name = "123" fmt.Println(a.name) // fmt.Println("TZ") } 方法访问权限 // 属性的访问范围是在`package`中的可以访问的,如果需要在外部包中访问,需要大写字母 type A struct { name string } func main () { a := A{} a.Print() fmt.Println(a.name) } func (a *A) Print() { a.name = "123" fmt.Println(a.name) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |