exaple1-slice切片
slice和数组的区别在于,数组有固定大小,slice没有固定大小,可以进行自增,相当于C++中的vector
append函数
通过append函数可以增加切片里面的元素。
make([]type)函数
通过make函数可以创建一个类型为type的切片,也可以直接创建一个空的切片
st:=[] int{} //创建一个空的切片
st=append(st, 5)
fmt.Println(st)
copy(a,b)函数
通过copy函数,可以将切片b进行复制到a中
slice()函数
通过a:=s[1:3],可以将1-3不包括3的切片进行分割
多维切片,也就是切片里面包含切片
twoD:=make([][]int,3)
package main
import "fmt"
func main() {
s:=make([]string,3)
fmt.Println("emp:",s)
s[0]="a"
s[1]="b"
s[2]="c"
fmt.Println("set:",s)
fmt.Println("get",s[2])
fmt.Println(len(s))
s=append(s,"d")
s=append(s,"e","f")
fmt.Println("apd",s)
c:=make([]string,len(s))
copy(c,s)
fmt.Println(c)
tmp:=s[2:5]
fmt.Println(tmp)
t:=[]string{"g","h","i"}
fmt.Println(t)
twoD:=make([][]int,3)
for i:=0;i<3;i++{
innerLen:=i+1
twoD[i]=make([]int,innerLen)
for j:=0;j<innerLen;j++{
twoD[i][j]=i+j
}
}
fmt.Println("2d:",twoD)
}
map字典、哈希表
创建map
m:=make(map[int] string) //使用map创建
st:= map[string]int{} //直接创建
len()求map的长度
package main
import "fmt"
func main() {
m:=make(map[int] string)
m[1]="sting"
m[5]="string"
for i:=0;i<len(m);i++{
if(len(m[i])==0){
fmt.Println("null")
}else{
println(m[i])
}
}
st:= map[string]int{}
st["a"]=1023
st["b"]=103
fmt.Println(st)
_,prs:=m[1]
fmt.Println(prs)
}
/*
null
map[a:1023 b:103]
true
sting
*/
range
利用range可以来遍历数组,切片,字典。
package main
import "fmt"
func main() {
nums:=[]int{1,2,3,4,5}
sum:=0
for _,val:=range nums{
sum+=val
}
fmt.Println("sum:",sum) //返回15
for i,val:=range nums{
if val==3{
fmt.Println("index",i)
}
}
kvs:=map[string]string{"a":"apple","b":"banana"}
for k,v:=range kvs{
fmt.Printf("%s->%s\n",k,v)
}
for k:=range kvs{
fmt.Println("key:",k)
}
for i,c:=range "go"{
fmt.Println(i,c)
}
}
Function
单一返回值
函数在golang中是一等公民
package main
import "fmt"
func plus(a int,b int) int {
ret:=a+b
return ret
}
func main() {
res:=plus(1,2)
fmt.Println(res)
}
多返回值
package main
import "fmt"
func vals()(int,int) {
return 3,7
}
func main() {
a,b:=vals()
fmt.Println(a)
fmt.Println(b)
_,c:=vals()
fmt.Println(c)
}
可变参函数 Variadic Functions
package main
import "fmt"
func sum(nums ...int) {
fmt.Println(nums)
total:=0
for _,val:=range nums{
total+=val
}
fmt.Println(total)
}
func main() {
sum(1,2)
sum(1,2,3)
sum(1,2,3,4)
nums:=[]int {1,3,5,7,9}
sum(nums...)
}
函数闭包 Closures
package main
import (
"fmt"
"reflect"
)
func intSeq()func() int {
i:=0
return func() int {
i++
return i
}
}
func main() {
nextInt:=intSeq()
for i:=0;i<3;i++{
fmt.Println(nextInt())//这里返回1 2 3
}
fmt.Println(reflect.TypeOf(intSeq())) //这里返回 func() int
newFunc:=intSeq()
fmt.Println(newFunc()) //这里返回1
}
递归函数 Recursion
package main
import "fmt"
func fact(n int) int {
if n==0{
return 1
}
return n*fact(n-1)
}
func main() {
fmt.Println(fact(5))
}
指针 Pointer
package main
import "fmt"
func zeroval(ival int) {
ival=0
}
func zeroptr(iptr *int) {
*iptr=0
}
func main() {
i:=1
fmt.Println("initial",i) //1
zeroval(i)
fmt.Println("zeroval:",i) //1
zeroptr(&i)
fmt.Println("zeroptr:",i) //0
fmt.Println("pointer",&i) //0xc00000a098
}
/*
initial 1
zeroval: 1
zeroptr: 0
pointer 0xc00000a098
*/
传值过去和传地址过去,传值过去无法改变实参,只能通过形参改变。
结构体struct
package main
import "fmt"
type person struct {
name string
age int
}
func newPerson(name string) *person{
p:=person{name:name}
p.age=42
return &p
}
func main() {
fmt.Println(person{"Bob",20})
fmt.Println(person{name:"Alice",age: 30})
fmt.Println(person{name:"JackMa"})
fmt.Println(&person{name:"Ann",age: 40})
fmt.Println(newPerson("Jon"))
s:=person{name:"Steven",age: 50}
fmt.Println(s.name)
sp:=&s
fmt.Println(sp.age)
sp.age=51
fmt.Println(sp.age)
}
/*
{Bob 20}
{Alice 30}
{JackMa 0}
&{Ann 40}
&{Jon 42}
Steven
50
51
*/
Methods 方法
package main
import "fmt"
type rect struct {
width,height int
}
func (r *rect) area()int { //接收输入的类型为 *rect
return r.height*r.width
}
func (r *rect) perim()int { //接收输入的类型为 *rect
return 2*r.width+2*r.height
}
func area2(r rect ) int { //接收输入的形参为 rect
return r.width*r.height
}
func perim2(r rect) int { //接收输入的形参为 rect
return 2*r.height+2*r.width
}
func main() {
r:=rect{width: 100,height: 200}
fmt.Println("面积为:",r.area())
fmt.Println("周长为:",r.perim())
rp:=&r
fmt.Println("rp面积为:",rp.area())
fmt.Println("rp周长为:",rp.perim())
fmt.Println("-----------------")
fmt.Println(area2(r))
fmt.Println(perim2(r))
}
/*
面积为: 20000
周长为: 600
rp面积为: 20000
rp周长为: 600
-----------------
20000
600
*/
interface 接口
package main
import (
"fmt"
"math"
"reflect"
)
type geo interface {
area() float64
perm() float64
}
type circle struct {
radius float64
}
type rectangle struct {
width float64
height float64
}
func (r rectangle)area() float64 {
return r.width*r.height
}
func (r rectangle)perm() float64 {
return 2*r.width+2*r.height
}
func (c circle)area() float64 {
return math.Pi*c.radius*c.radius
}
func (c circle)perm() float64 {
return math.Pi*c.radius*2
}
func measure(g geo) {
fmt.Println(reflect.TypeOf(g))
fmt.Println(g.area())
fmt.Println(g.perm())
}
func main() {
r:=rectangle{width: 100,height: 200}
c:=circle{radius: 10}
measure(r)
measure(c)
}
/*
Output Result:
main.rectangle
20000
600
main.circle
314.1592653589793
62.83185307179586
*/
ERRORS
Goroutines 协程
协程就是微线程,协程是编译器级别的,而线程是操作系统级别的。一个进程有多个线程。
package main
import (
"fmt"
"time"
)
func f(str string) {
for i:=0;i<3;i++{
fmt.Println(str,":",i)
}
}
func main() {
f("string")
go f("abcdefg")
go func(msg string) {
fmt.Println(msg)
}("going")
time.Sleep(time.Second)
fmt.Println("done")
}
/*
string : 0
string : 1
string : 2
going
abcdefg : 0
abcdefg : 1
abcdefg : 2
done
*/
Channels 通道
通道是用于协程信息的传递,
package main
import "fmt"
func main() {
message :=make(chan string)
str:="This is a string!"
go func() {message <- str}()
msg:=<-message
fmt.Println(msg)
}
Channels Buffering 通道缓冲区
package main
import "fmt"
func main() {
message:=make(chan string,3)
str:="this is a string"
message <-str
message <-"buffering!"
message <-"channels"
for i:=0;i<3;i++{
fmt.Println(<-message)
}
}
/*
输出结果:
this is a string
buffering!
channels
*/
Channel Synchronization 同步通道
package main
import (
"fmt"
"time"
)
func worker(done chan bool) {
fmt.Println("working...")
time.Sleep(time.Second)
fmt.Println("done")
done<-true
}
func main() {
done :=make(chan bool,1)
go worker(done)
fmt.Println(<-done)
}
/*
working...
done
true
*/