2019年12月13日10:35:20
1.介绍
2019年10月31日15:09:03







2.基本语法
2.1 定义变量
2019年10月31日16:12:34
1.函数外必须使用var定义变量

var a=1 b:=5
声明变量的一般形式是使用 var 关键字:
var name type
其中,var 是声明变量的关键字,name 是变量名,type 是变量的类型。
2.没有全局变量说法,只有包变量
3.集中定义变量
var ( a int c string d bool )
4.使用var关键字
var a,b,c bool var s1,s2 string="hello","world"
5.使用:=定义变量
只能在函数体内使用
a,b,c:=1,2,"123"
6.基本类型
Go语言的基本类型有: bool string int、int8、int16、int32、int64 uint、uint8、uint16、uint32、uint64、uintptr byte // uint8 的别名 rune // int32 的别名 代表一个 Unicode 码 float32、float64 complex64、complex128
7.源代码:
package main import "fmt" var ( a int c string d bool ) func main() { varible() varibleType() varibleSimple() fmt.Println(d) } func varible(){ var s int var t string fmt.Printf("%d %q\n",s,t) } func varibleSimple(){ a,b,c :=1,2,"abc" b=5 fmt.Println(a,b,c) } func varibleType(){ var a,b,c=1,2,"abc" fmt.Println(a,b,c) }
2.2 go内建变量类型
2019年10月31日16:26:53
1.复数类型
两种复数类型,分别是 complex64(32 位实数和虚数)类型和 complex128(64 位实数和虚数)类型。
内置的 complex 函数用于构建复数,内建的 real 和 imag 函数分别返回复数的实部和虚部:
var x complex128 = complex(1, 2) // 1+2i var y complex128 = complex(3, 4) // 3+4i fmt.Println(x*y) // "(-5+10i)" fmt.Println(real(x*y)) // "-5" fmt.Println(imag(x*y)) // "10"
复数使用 re+imi 来表示,其中 re 代表实数部分,im 代表虚数部分,i 代表根号负 1。如果一个浮点数或一个十进制整数后面跟着一个 i,例如 3.141592i 或 2i,它将构成一个复数的虚部,而复数的实部是 0
fmt.Println(1i * 1i) // "(-1+0i)", i^2 = -1
2.强制类型转换
类型转换是强制的
规定是什么类型的参数一定要必须是
返回什么类型也得强转。
3.正弦
正弦函数由 math 包提供,函数入口为 math.Sin,正弦函数的参数为 float64,返回值也是 float64。在使用正弦函数时,根据实际精度可以进行转换。
2.3 常量与枚举
2019年10月31日18:08:39
1.常量
//常量 const s,t=1,2 const y int=5
2.枚举
iota 开始生成枚举值, 默认为0
iota 不仅可以生成每次增加 1 的枚举值。还可以利用 iota 来做一些强大的枚举常量值生成器
//枚举 func enums() { const( cpp=iota java python golang ) //b,kb,mb,gb,tb,pb const( b=1<<(10*iota) kb mb gb tb pb ) fmt.Println(cpp,java,python,golang) fmt.Println(b,kb,mb,gb,tb,pb) }
3.总结
- 变量类型写在变量名之后
- 编译器可推测变量类型
- 没有char,只有rune
- 原生支持复数类型
2.4 条件语句
2019年10月31日18:24:56
1.if的条件里不需要括号
func varible1() int { var a int=5 if a>3 { return 100 }else{ return 122 } }
2.if的条件里可以赋值
if contents,err:=ioutil.ReadFile(filename); err!=nil{ fmt.Println(err) }else { fmt.Println("%s\n", contents) }
3.switch
func eval(a,b int,op string) int{ var result int switch op { case "+": result = a + b case "-": result = a - b default: panic("unsupported" + op) } return result }
4.switch会自动break,除非使用fallthrough
5.switch后可以没有表达式

6.源码
package main import ( "fmt" "io/ioutil" ) func main() { const filename="abc.txt" //contents,err:=ioutil.ReadFile(filename) //if err!=nil{ // fmt.Println(err) //}else { // fmt.Println("%s\n",contents) //} // //fmt.Println(contents) if contents,err:=ioutil.ReadFile(filename); err!=nil{ fmt.Println(err) }else { fmt.Println("%s\n", contents) } fmt.Println(eval(3,1,"+")) } func varible1() int { var a int=5 if a>3 { return 100 }else{ return 122 } } func eval(a,b int,op string) int{ var result int switch op { case "+": result = a + b case "-": result = a - b default: panic("unsupported" + op) } return result }
2.5 循环
2019年10月31日19:12:25
1.for的条件里不需要括号
//整数转成二进制 func main() { fmt.Println( convertToBin(5), convertToBin(15), ) } //循环 func convertToBin(n int) string { result:="" for ;n>0;n/=2{ lsb:=n%2 result=strconv.Itoa(lsb)+result } return result }
2.没有while
3.源码
package main import ( "bufio" "fmt" "os" "strconv" ) func main() { fmt.Println( convertToBin(5), convertToBin(15), ) printFile("abc.txt") } //循环 func convertToBin(n int) string { result:="" for ;n>0;n/=2{ lsb:=n%2 result=strconv.Itoa(lsb)+result } return result } //读取文本 func printFile(filename string){ file,err:=os.Open(filename) if err!=nil{ panic(err) }else{ scanner:=bufio.NewScanner(file) for scanner.Scan(){ fmt.Println(scanner.Text()) } } }
2019年10月31日19:28:28
2.6 函数
2019年10月31日19:28:41
1.函数可以返回多个值
func div(a,b int)(q,r int){ return a/b,a%b } func main() { fmt.Println(123) div(13,4) }
2.返回多个值可以起名字
3.没有默认参数,可选参数
4.介绍
函数的基本组成为:关键字 func、函数名、参数列表、返回值、函数体和返回语句,每一个程序都包含很多的函数,函数是基本的代码块。
因为Go语言是编译型语言,所以函数编写的顺序是无关紧要的,
鉴于可读性的需求,最好把 main() 函数写在文件的前面,其他函数按照一定逻辑顺序进行编写(例如函数被调用的顺序)。
2.7 指针
2019年10月31日20:19:48
1.指针不能运算
指针(pointer)在Go语言中可以被拆分为两个核心概念:
- 类型指针,允许对这个指针类型的数据进行修改,传递数据可以直接使用指针,而无须拷贝数据,类型指针不能进行偏移和运算。
- 切片,由指向起始元素的原始指针、元素数量和容量组成。
切片比原始指针具备更强大的特性,而且更为安全。切片在发生越界时,运行时会报出宕机,并打出堆栈,而原始指针只会崩溃。
2.go语言只有值传递


3.
每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用在变量名前面添加&
ptr := &v // v 的类型为 T
其中 v 代表被取地址的变量,变量 v 的地址使用变量 ptr 进行接收,ptr 的类型为*T
称做 T 的指针类型,*
代表指针。
3.数组切片容器
3.1 数组
2019年10月31日20:37:02
1.定义数组的集中方法
var arr1 [5]int arr2:=[3]int{1,3,5} arr3:=[...]int{2,4,6,8,10} var grid [4][5]int fmt.Println(arr1,arr2,arr3) fmt.Println(grid)

2.遍历数组 range
//传统方式 for i:=0;i< len(arr3);i++{ fmt.Println(arr3[i]) }
使用range
for i:=range arr3{ fmt.Println(arr3[i]) }
获得索引和值
for i,v:=range arr3{ fmt.Println(i,v) }

3.range遍历时索引不想用到
for _,v:=range arr3{ fmt.Println(v) }
4.为什么用到range

5.数组是值类型
6.[10]int 和[20]int是不同类型
7.调用func f(arr [10]int)会 拷贝 数组
8.go语言一般不直接使用数组
3.2 切片-slice
2019年10月31日20:55:34

1.介绍
切片(slice)是对数组的一个连续片段的引用,所以切片是一个引用类型(因此更类似于 C/C++ 中的数组类型,或者 Python 中的 list 类型)
这个片段可以是整个数组,也可以是由起始和终止索引标识的一些项的子集,需要注意的是,终止索引标识的项不包括在切片内。
切片一般用于快速地操作一块数据集合,如果将数据集合比作切糕的话,切片就是你要的“那一块”,切的过程包含从哪里开始(切片的起始位置)及切多大(切片的大小),容量可以理解为装切片的口袋大小,如下图所示。

2.切片是对数组的视图,同步更新。
//更新视图 func updateArr(arr []int){ arr[0]=1000 } func main() { arr3:=[...]int{2,4,6,7,8,5,4,33} s:=arr3[2:6] fmt.Println(s) fmt.Println("arr[:6]= ",arr3[:6]) fmt.Println("arr[2:]= ",arr3[2:]) fmt.Println("arr[:]= ",arr3[:]) s1:=arr3[2:] s2:=arr3[:] updateArr(s1) fmt.Println("更新过的s1:=",s1) fmt.Println("更新过的arr:=",arr3) updateArr(s2) fmt.Println("更新过的s2:=",s2) fmt.Println("更新过的arr:=",arr3) }

3.slice本身没有数据,是对底层array的一个view
4.resilce,不断的切片
5.slice扩展
4.为什么用到range


arr:=[...]int{1,2,3,4,5,6,7,8} fmt.Println("arr:=",arr) s1:=arr[2:6] s2:=s1[3:5] fmt.Printf("s1=%v,len(s1)=%d,cap(s1)=%d\n",s1,len(s1),cap(s1)) fmt.Printf("s2=%v,len(s2)=%d,cap(s2)=%d\n",s2,len(s2),cap(s2))

6.slice实现

7.slice可以向后扩展,不可以向前扩展
8.s[i]不可以超越len(s),向后扩展不可以超越底层数组cap(s)
9.向slice添加元素
s4和s5不再是arr的视图了
s3:= append(s2, 10) s4:=append(s3,11) s5:=append(s4,12) fmt.Println("s3,s4,s5",s3,s4,s5) fmt.Println("arr:=",arr)

10.添加元素时超越cap,系统会重新分配更大的底层数组
11.由于值传递,必须接受append的返回值
s=append(s,val)
12.定义slice
var s []int
13.知道长度,初始化slice
func printSilce(arr []int){ fmt.Printf("s=%v,len=%d,cap=%d\n",arr,len(arr),cap(arr)) } func main() { s1:=[]int{2,4} printSilce(s1) s2:=make([]int,16) s3:=make([]int,16,32) printSilce(s2) printSilce(s3) }

14.copy slice
copy(s2,s1)
15.slice删除某个元素
copy(s2,s1) printSilce(s2) s5:=append(s2[:3],s2[4:]...) printSilce(s5)

16.删除头尾
//删除头尾 front:=s5[0] s5=s5[1:] tail:=s5[len(s5)-1] s5=s5[:len(s5)-1] fmt.Println(front,tail) printSilce(s5)

2019年11月01日13:03:18
3.3 map
2019年11月01日13:03:26
1.介绍
Go语言中 map 是一种特殊的数据结构,一种元素对(pair)的无序集合,pair 对应一个 key(索引)和一个 value(值),所以这个结构也称为关联数组或字典,这是一种能够快速寻找值的理想结构,给定 key,就可以迅速找到对应的 value。
2.map建立方式
m:=map[string] string{ "name":"jixi", "age":"13", } m3:=make(map[string]int) fmt.Println(m,m3)

3.遍历map
for i,v :=range m{ fmt.Println(i,v) }
4.取得对应key的value
m2:=m["name"] fmt.Println(m2)
5.删除元素
fmt.Println("_____________删除元素") delete(m,"name") fmt.Println(m)
6.判断是否存在key
value,ok:=m[key]
7.除了slice,map,func的内建类型都可以作为key
4.面向对象
4.1 结构体和方法
2019年11月01日13:46:19
1.仅支持封装,不支持继承和多态。
2.go没有class,只有struct
3.不论地址还是结构本身,一律采用.来访问成员
type treeNode struct { value int left,right *treeNode } func main() { var root treeNode root=treeNode{value:3} root.left=&treeNode{value:10} root.right=&treeNode{5,nil,nil} root.right.right=new(treeNode) fmt.Println(root) }
4.结构的创建

//工厂函数 func createNode(value int) *treeNode{ return &treeNode{value:value} }
5.为结构定义方法

//定义方法 func (node treeNode) print() { fmt.Print(node.value) } root.print()
6.方法的不同
不带指针:就是拷贝一份数据,实际上不修改原来的值
带指针:会把地址传过去
//定义方法 func (node treeNode) print() { fmt.Println(node.value) } //带指针 func (node *treeNode) setValue(value int){ node.value=value } func main() { var root treeNode root=treeNode{value:3} root.left=&treeNode{value:10} root.right=&treeNode{5,nil,nil} root.right.right=new(treeNode) //fmt.Println(root) root.print() root.setValue(200) root.print() }

7.源码
node.go
package tree import "fmt" type Node struct { Value int Left, Right *Node } func (node Node) Print() { fmt.Print(node.Value, " ") } func (node *Node) SetValue(value int) { if node == nil { fmt.Println("Setting Value to nil " + "node. Ignored.") return } node.Value = value } func CreateNode(value int) *Node { return &Node{Value: value} }
traversal.go
package tree import "fmt" func (node *Node) Traverse() { node.TraverseFunc(func(n *Node) { n.Print() }) fmt.Println() } func (node *Node) TraverseFunc(f func(*Node)) { if node == nil { return } node.Left.TraverseFunc(f) f(node) node.Right.TraverseFunc(f) } func (node *Node) TraverseWithChannel() chan *Node { out := make(chan *Node) go func() { node.TraverseFunc(func(node *Node) { out <- node }) close(out) }() return out }
entry.go
package main import ( "fmt" "imooc.com/ccmouse/learngo/tree" ) type myTreeNode struct { node *tree.Node } func (myNode *myTreeNode) postOrder() { if myNode == nil || myNode.node == nil { return } left := myTreeNode{myNode.node.Left} right := myTreeNode{myNode.node.Right} left.postOrder() right.postOrder() myNode.node.Print() } func main() { var root tree.Node root = tree.Node{Value: 3} root.Left = &tree.Node{} root.Right = &tree.Node{5, nil, nil} root.Right.Left = new(tree.Node) root.Left.Right = tree.CreateNode(2) root.Right.Left.SetValue(4) fmt.Print("In-order traversal: ") root.Traverse() fmt.Print("My own post-order traversal: ") myRoot := myTreeNode{&root} myRoot.postOrder() fmt.Println() nodeCount := 0 root.TraverseFunc(func(node *tree.Node) { nodeCount++ }) fmt.Println("Node count:", nodeCount) c := root.TraverseWithChannel() maxNodeValue := 0 for node := range c { if node.Value > maxNodeValue { maxNodeValue = node.Value } } fmt.Println("Max node value:", maxNodeValue) }
4.2 包和封装
2019年11月01日14:33:25
封装
1.名字一般使用CamelCase
2.首字母大写: public
3.首字母小写:private
package tree import "fmt" type Node struct { Value int Left, Right *Node } //工厂函数 func createNode(value int) *Node { return &Node{Value: value} } //定义方法 func (node Node) Print() { fmt.Println(node.Value) } //带指针 func (node *Node) SetValue(value int){ node.Value =value }
package main import "awesomeProject/src/tree" func main() { var root tree.Node root=tree.Node{Value: 3} root.Left=&tree.Node{Value: 10} root.Right=&tree.Node{5,nil,nil} root.Right.Right=new(tree.Node) //fmt.Println(root) root.Print() root.SetValue(200) root.Print() }
4.2 包
4.每个目录一个包
5.main包包含可执行入口
6.为结构定义的方法必须放在同一个包内,但是可以是不同文件
7.封装的好处:
- 隐藏实现细节;
- 可以对数据进行验证,保证数据安全合理。
如何体现封装:
- 对结构体中的属性进行封装;
- 通过方法,包,实现封装。
封装的实现步骤:
- 将结构体、字段的首字母小写;
- 给结构体所在的包提供一个工厂模式的函数,首字母大写,类似一个构造函数;
- 提供一个首字母大写的 Set 方法(类似其它语言的 public),用于对属性判断并赋值;
- 提供一个首字母大写的 Get 方法(类似其它语言的 public),用于获取属性的值。
8.常用内置包
1) fmt
包 fmt 实现了格式化的 I/O 函数,这与 C 的 printf 和 scanf 类似。格式化短语派生于 C 。一些短语(%-序列)这样使用:
2) io
这个包提供了原始的 I/O 操作界面。它主要的任务是对 os 包这样的原始的 I/O 进行封装,增加一些其他相关,使其具有抽象功能用在公共的接口上。
这个包实现了缓冲的 I/O。它封装于 io.Reader 和 io.Writer 对象,创建了另一个对象(Reader 和 Writer)在提供缓冲的同时实现了一些文本 I/O 的功能。
4) sort
sort 包提供了对数组和用户定义集合的原始的排序功能。
strconv 包提供了将字符串转换成基本数据类型,或者从基本数据类型转换为字符串的功能。
6) os
os 包提供了与平台无关的操作系统功能接口。其设计是 Unix 形式的。
sync 包提供了基本的同步原语,例如互斥锁。
8) flag
flag 包实现了命令行解析。
encoding/json 包实现了编码与解码 RFC 4627 定义的 JSON 对象。
10) html/template
数据驱动的模板,用于生成文本输出,例如 HTML。
将模板关联到某个上进行解析。模板内容指向数据结构的元素(通常结构的字段或者 map 的键)控制解析并且决定某个值会被显示。模板扫描结构以便解析,而“游标” @ 决定了当前位置在结构中的值。
11) net/http
net/http 实现了 HTTP 请求、响应和 URL 的解析,并且提供了可扩展的 HTTP 服务和基本的 HTTP 客户端。
unsafe 包包含了 Go 程序中数据类型上所有不安全的操作。通常无须使用这个。
13) reflect
reflect 包实现了运行时反射,允许程序通过抽象类型操作对象。通常用于处理静态类型 interface{} 的值,并且通过 Typeof 解析出其动态类型信息,通常会返回一个有接口类型 Type 的对象。
os/exec 包执行外部命令。
4.3 扩展已有类型
2019年11月01日14:49:06
1.如何扩充系统类型或者别人的类型
- 定义别名
- 使用组合
4.4 gopath
2019年11月01日15:12:38
1.

2.查看gopath
apple$ pwd /Users/apple/go/src/awesomeProject/src apple$ echo $GOPATH /Users/apple/go/src/awesomeProject/src:/Users/apple/go/src/awesomeProject :/Users/apple/go apple$ cat ~/.bash_profile PATH=$PATH:/usr/local/mysql/bin export GOPATH="/Users/apple/go" export PATH=$PATH:$GOPATH/bin export GOROOT=/usr/local/go
3.



2019年12月16日16:51:53
END
来源:https://www.cnblogs.com/oneapple/p/12049968.html