Go语法的基本使用(三)
// 长度 vs 容量、
// 长度是目前里面有几个值
// 容量是最多能放多少个值
func main(){
var a =make(chan int,4)
a<-1
a<-2
a<-5
fmt.Println(len(a)) //3
fmt.Println(cap(a))// 45
<-a // 取值
fmt.Println(len(a)) // 2
fmt.Println(cap(a)) // 4
}
一.协程
package main import (
"fmt"
"time"
) //go 协程 func test() {
fmt.Println("hello go")
}
func main() {
//goroutine
go test()
go test()
go test()
go test()
go test()
go test()
go test()
time.Sleep(time.Second*2)
}
二.值的存 和取
package main import (
"fmt" ) // (2)信道 管道 通道 // 信道也是个变量
// 类型:信道运输的类型是int 类型
// 性质:是一种引用的类型 所以需要在初始化的时候就得付初始值 func task2(a chan bool) {
fmt.Println("hello go ")
// IO 一旦执行完毕,就往信道中放入一个值 a <- true // 存值
fmt.Println("")
} // 入口函数 理解 func main(){
// 必须初始化
var a chan bool = make(chan bool)
// 执行函数
go task2(a)
// 往里面存值 // <- a// 取值
x:=<-a
fmt.Println(x) }
------------恢复内容结束------------
一. 在方法中使用 值 接收器 与 在函数中使用 值 参数
(1)定义用一个外部函数(接收器:接收值)方法中使用值接收器方法
package main import "fmt" // 在方法中使用 值 接收器 与 在函数中使用 值 参数
// 在方法中使用 指针 接收器 与函数再使用 指针 参数
// 结构体
type Person5 struct{
name string
age int
sex int } // (1)定义用一个外部函数(接收器:接收值)方法中使用值接收器方法
func (a Person5)printName(){
fmt.Println(a.name)
fmt.Println(a.age)
fmt.Println(a.sex) } func main(){
// 定义一个变量
p:=Person5{name:"tt",age:18,sex:1}
// 调用值接收器
p.printName()
(2)方法中使用指针接收器
package main import "fmt" // 函数中使用 指针传值 // (1)定义一个结构体
type Person2 struct {
name string
age int
sex int
} // (2)定义一个函数 中功能代码
func (a *Person2)printName(){
// 需要执行的功能 哈
fmt.Println(a.name)
fmt.Println(a.age)
} // (3)入口函数
func main(){
// 定义结构体的变量
// var t *Person2=&Person2{name:"tt",age:18,sex:2}
t:=&Person2{name:"tt",age:18,sex:2} // 值的传递可以省略类型
t.printName()
}
(3)函数的值传递和指针传递
函数中使用值参数
// (1)定义结构体
type Person2 struct{
name string
age string
sex int
id int
} // (2)定义一个外部功能函数 参数和结构体一一对应 其实还有返回值
func printName(a Person2){
fmt.Println(a.name)
fmt.Println(a.age)
fmt.Println(a.sex)
fmt.Println(a.id) } // (3)入口函数 >>>> url 地址的入口 func main() {
// (4)定义结构的变量的初始值
//p:=Person2{} //字符串则是 空 数字 则是0
//fmt.Println(p,"---==")
p:=Person2{name:"yy",age:"",sex:2} // 不设置数字就是0
printName(p) // 函数就是传值 接收器(a Person) p点方法
}
(4)函数中的指针传递参数
package main import "fmt" // (4)函数中的指针传递值 // (1)go语言定义结构体
type Person2 struct{
name string
age int
sex int
id int
} // (2)外部执行功能函数 func printName(a *Person2){
fmt.Println(a.name)
fmt.Println(a.age)
fmt.Println(a.sex)
fmt.Println(a.id) } // (3)入口函数
func main(){
// (4)定义变量及初始化
p:=&Person2{age:18,name:"yuyu",sex:1,id:13} // 指名道姓 无关顺序 printName(p) // &p和上面的一样获取地址 }
一.接收器如果不能进行识别需要进行重命名
package main import "fmt" // 在非结构体上的方法 》》》重命名 接收器
type MyInt int
func (i *MyInt) add(){
(*i)++
fmt.Println(*i) // 11 } func main() {
// 定义一个变量
var a MyInt=10
a.add() // 接收器传值
fmt.Println(a) // 引用11 }
三,接口:是一系类方法的集合
(1)实现方式一:接收器 传值 >>> mian 中点方法进行调用
package main import "fmt" // 接口 继承 封装 多态 ,鸭子类型 重点*****
// 接口:一系列方法的集合
// (1)语法:
// type 接口名 interface{
// test方法一()
// 方法二功能()
// } // >>>(1)定义一个鸭子类的接口
type Duck interface{
run()
speak() } // 结构体实现该接口(只要实现了接口中的所方法,该结构体实现了Duck接口)
// >>>(2)定义一普通胖鸭子类 结构体
type PDuck struct {
// 属性
name string
age string
id int } // (3)接口函数的值的传递
func (p PDuck) run(){
fmt.Println("我是第一只胖鸭子 会run") } func (p PDuck)speak(){
fmt.Println("我是第一只胖鸭子 会speak")
} // 定义一只唐老鸭 结构体
type TDuck struct { name string
age string
wife bool
} // 定义TDduct 的方法 不用函数实现
func (p TDuck) run(){
fmt.Println("我是唐老鸭 会run ")
fmt.Println(p.name)
} // 再定义一个speak 接收器方法 func (p TDuck) speat(){
fmt.Println("我是唐老鸭 会speak")
fmt.Println(p.wife,"") // } // (3)函数入口
func main(){
pD:=PDuck{name:"胖鸭子"}
tD:=TDuck{name:"唐老鸭"}
// 写一个函数:让鸭子说话,不管是唐老鸭还是胖鸭子
pD.speak() // 我是第一只胖鸭子 会speak 可以调
tD.speat() // 我是唐老鸭 会speak
(2)实现接收器中函数的 run() 和speak() 方法 方法二:定义普通函数 在普通函数体内进行 run() 同时在我们的main中 调用 普通函数
package main import "fmt" // 接口 继承 封装 多态 ,鸭子类型 重点*****
// 接口:一系列方法的集合
// (1)语法:
// type 接口名 interface{
// test方法一()
// 方法二功能()
// } // >>>(1)定义一个鸭子类的接口
type Duck interface{
run()
speak() } // 结构体实现该接口(只要实现了接口中的所方法,该结构体实现了Duck接口)
// >>>(2)定义一普通胖鸭子类 结构体
type PDuck struct {
// 属性
name string
age string
id int } // (3)接口函数的值的传递
func (p PDuck) run(){
fmt.Println("我是第一只胖鸭子 会run") } func (p PDuck)speak(){
fmt.Println("我是第一只胖鸭子 会speak")
} // 定义一只唐老鸭 结构体
type TDuck struct { name string
age string
wife bool
} // 定义TDduct 的方法 不用函数实现
func (p TDuck) run(){
fmt.Println("我是唐老鸭 会run ")
fmt.Println(p.name)
} // 再定义一个speak 接收器方法 func (p TDuck) speat(){
fmt.Println("我是唐老鸭 会speak")
fmt.Println(p.wife,"") // } // (3)函数入口
func main(){
pD:=PDuck{name:"胖鸭子"}
tD:=TDuck{name:"唐老鸭"}
// 写一个函数:让鸭子说话,不管是唐老鸭还是胖鸭子
//pD.speak() // 我是第一只胖鸭子 会speak 可以调
//tD.speat() // 我是唐老鸭 会speak
//// speak(tD,"yyyy") //接收器 不是函数 不能传值
// 同时实现speak
speak2(tD) 调用普通函数
speak(pD)
// XXX(pD)
var d Duck
d=pD
// d=tD
fmt.Println(d,"xxxx") // {唐老鸭 false} xxxx }
// (4)函数 的传值
func speak(p PDuck){
p.speak() 调用接收器中的方法
} func speak2(p TDuck){
p.speat()
} func XXX(p PDuck){
p.run() // 在一个函数调用另一个函数
fmt.Println(p.name) 调用接收器的方法
}
四、断言 switch 判断子类的属性和方法
package main import "fmt" // 接口 继承 封装 多态 ,鸭子类型 重点*****
// 接口:一系列方法的集合
// (1)语法:
// type 接口名 interface{
// test方法一()
// 方法二功能()
// } // >>>(1)定义一个鸭子类的接口
type Duck interface{
run()
speak() } // 结构体实现该接口(只要实现了接口中的所方法,该结构体实现了Duck接口)
// >>>(2)定义一普通胖鸭子类 结构体
type PDuck struct {
// 属性
name string
age string
id int } // (3)接口函数的值的传递
func (p PDuck) run(){
fmt.Println("我是第一只胖鸭子 会run") } func (p PDuck)speak(){
fmt.Println("我是第一只胖鸭子 会speak")
} // 定义一只唐老鸭 结构体
type TDuck struct { name string
age string
wife bool
} // 定义TDduct 的方法 不用函数实现
func (p TDuck) run(){
fmt.Println("我是唐老鸭 会run ")
fmt.Println(p.name)
} // 再定义一个speak 接收器方法 func (p TDuck) speat(){
fmt.Println("我是唐老鸭 会speak")
fmt.Println(p.wife,"") // } // (3)函数入口
func main(){
pD:=PDuck{name:"胖鸭子"}
tD:=TDuck{name:"唐老鸭"}
// 写一个函数:让鸭子说话,不管是唐老鸭还是胖鸭子
//pD.speak() // 我是第一只胖鸭子 会speak 可以调
//tD.speat() // 我是唐老鸭 会speak
//// speak(tD,"yyyy") //接收器 不是函数 不能传值
// 同时实现speak
speak2(tD) 调用普通函数
speak(pD)
// XXX(pD)
var d Duck
d=pD
// d=tD
fmt.Println(d,"xxxx") // {唐老鸭 false} xxxx }
// (4)函数 的传值
func speak(p PDuck){
p.speak() 调用接收器中的方法
} func speak2(p TDuck){
p.speat()
} func XXX(p PDuck){
p.run() // 在一个函数调用另一个函数
fmt.Println(p.name) 调用接收器的方法
}
截图suoshi:
空接口
package main import "fmt" // 空接口(一个方法都没有)
// 匿名空接口
// 所有的数据类型都实现了空接口
// 类似于一个父类
type Empty interface{ } type TDuck2 struct {
name string
age int
wife bool } // 入口函数
func main(){
test3(1)
test3("sss")
test3(TDuck2{})
test3(10.233432423) //var a Empty=1
//var b Empty="IOOIO"
} //func test(a Empty){
// fmt.Println(a)
//} func test3(a interface{}) {
switch a.(type) {
case int:
fmt.Println("int类型")
case string:
fmt.Println("string")
case TDuck2:
fmt.Println("老鸭子")
default:
fmt.Println("啥类型")
}
五.异常处理
package main import (
"fmt" ) // 异常处理
// defer 延迟调用 即便程序出现严重错误 也会执行
// panic 就是python中的raise(主动跑出异常)
// recover 恢复程序, 继续执行 func main() {
//先注册,后调用
//defere ????
fmt.Println("xxx")
// defere
fmt.Println("yyyy")
//f1() // 调用
f2() // 调用
//f3() // 调用
} func f1(){
fmt.Println("f1...") } func f2(){
defer func() {
if a:=recover();a!=nil{
// a 如果不等于nil, 表示程序出了异常, a就是异常信息
// a 等于nil 表示没有异常
fmt.Println("代码异常出错;了")
}//用于会被执行(相当于finally) }() // 这里执行函数
fmt.Println("f2...")
// var a = make([]int,3,3)
// fmt.Println(a[4])
panic("主动抛异常")
}
func f3(){
fmt.Println("f3...")
}
六。自定义set map 去重
package main import "fmt" // (1)自定义set() 可以放值 type MySet map[interface{}]bool
//func (s MySet)isExist(a interface{}) bool {
// return s[a] // 这只是个接口 判断
//} // 定义接口函数 interface{} 其实大可不必要用*号
func (s *MySet) set(a interface{}){
(*s)[a]=true //
} //用函数 就是一个普通的接收器函数// 可以查看长度
func (s MySet)len()int {
return len(s)
} // // 可以打印所有内容 MySet 》》》 类接收器
func (a MySet)printAll(){
for k,v:=range a{// 关键字range + s 变量
fmt.Println(k,v,"000--")
}
} func main() { // MySet = map[interface{}]bool 这个类型
var a MySet=make(MySet)
fmt.Println(a) // 空类型map[]
a.set("")
a.set("")
a.set("")
fmt.Println(len(a))
fmt.Println(a)
fmt.Println(a.len())
a.printAll() }
七.信道
(1)只写信道
package main import "fmt" // 单向信道只能放或 取 chan 关键字 a:=<-b 取 a<- 存取 箭头
func sendData(sendch chan<-int){
sendch<-10
} func main(){
//只写信道
sendch :=make(chan int)
go sendData(sendch)
fmt.Println(<-sendch)
}
(信道死锁的问题)
package main import "fmt" // 单向信道只能放或 取
//func sendData(sendch chan<-int){
// sendch<-10
//}
//
//func main(){
// //只写信道
// sendch :=make(chan int)
// go sendData(sendch)
// fmt.Println(<-sendch)
//} // 关闭信道和使用 for range 遍历信道 func task3(ccc chan int){
for i:=0;i<10;i++{
ccc<-i
}
close(ccc) // 关闭即可
} func main(){
// 类型定义
c:=make(chan int)
go task3(c)
// 死循环在监听我们的事件
for {
v,ok:=<-c
// 如果信道关闭,OK就是false
if ok==false{
break
}
fmt.Println("打印",v,ok)
} } // 出现死锁:fatal error: all goroutines are asleep - deadlock!
// 在for 循环结束后关闭存储任务 即可 解决死锁问题
2.信道缓存 》》》 设定缓存大小
(1)
package main import "fmt" // 信道缓冲
func main(){
// 初始化
var t chan int=make(chan int,1) // 0 前期缓存值
t<-1 // 将1 存入a 信道中 不写默认为0 根本存不进去
b:=<-t
fmt.Println("xxx",b)
}
(2)容量
package main import (
"fmt"
"time"
) // 列子 func write(ddd chan int){
// ddd 就相当于一个容器
for i:=0;i<10;i++{
ddd<-i }
close(ddd) } // 入口函数
func main() {
// 初始定义类型和信道类型 和 容量
var ddd chan int=make(chan int,5)
go write(ddd)
// 做io
time.Sleep(2*time.Second)
for v:=range ddd{
fmt.Println("reader value",v,"from ddd")
time.Sleep(2*time.Second)
} }
(3)容量和长度
// 长度 vs 容量、
// 长度是目前里面有几个值
// 容量是最多能放多少个值
func main(){
var a =make(chan int,4)
a<-1
a<-2
a<-5
fmt.Println(len(a)) //3
fmt.Println(cap(a))// 45
<-a // 取值
fmt.Println(len(a)) // 2
fmt.Println(cap(a)) // 4
}
(4)sync.WaitGroup
package main import (
"fmt"
"sync"
"time"
) // waitgroup:等待所有go协程执行完成
func task4(wg *sync.WaitGroup,i int){
time.Sleep(time.Second*2)
fmt.Println(i)
wg.Done() //
} func main(){
// sync包下的waitGroup,是个值类型,当参传递,需要地址
var wg sync.WaitGroup // 定义
for i:=0;i<5;i++ {
//wg.Add表示标志了起了一个goroutine
wg.Add(1)
go task4(&wg, i)
}
// 等待所有协程执行完成
wg.Wait()
fmt.Println("都执行完了")
}
(5)通过信道实现
//package main
//
//import (
//"fmt"
//"sync"
//"time"
//)
//
//// waitgroup:等待所有go协程执行完成
//func task4(wg *sync.WaitGroup,i int){
// time.Sleep(time.Second*2)
// fmt.Println(i)
// wg.Done() //
//}
//
//func main(){
// // sync包下的waitGroup,是个值类型,当参传递,需要地址
// var wg sync.WaitGroup // 定义
// for i:=0;i<5;i++ {
// //wg.Add表示标志了起了一个goroutine
// wg.Add(1)
// go task4(&wg, i)
// }
// // 等待所有协程执行完成
// wg.Wait()
// fmt.Println("都执行完了")
//
//}
package main import (
"fmt"
"time"
) // 通过信道实现
func main(){
var a =make(chan bool)
for i:=0;i<5;i++{
go task6(a,i) // 将信道和i 值传送到我们的函数中
}
for i:=0;i<5;i++{
<-a // 取值
}
fmt.Println("都执行完了")
}
// 传值传几个接收几个 以及类型 func task6(a chan bool,i int){
time.Sleep(time.Second*2)
fmt.Println(i)
a<-true // 将值存入我们a 信道中 }
七。中的锁
package main import (
"fmt"
"sync"
) // go 中的锁实现数据的安全 // 功能
var x=0
func incrament(wg *sync.WaitGroup,m *sync.Mutex){
// 布置锁
m.Lock()
x = x+10
m.Unlock()
wg.Done()
fmt.Println(x) // 从10开始 } func main(){
var w sync.WaitGroup // 定义变量
var m sync.Mutex // 定义锁 // 值类型 ,传递地址
for i:=0;i<1000;i++{
w.Add(1)
go incrament(&w,&m) }
w.Wait()
fmt.Println("都执行完毕了",x) // 拿到最后的值
}
(2)信道也是保证数据安全?
//package main
//
//import (
// "fmt"
// "sync"
//)
//
//// go 中的锁实现数据的安全
//
//// 功能
//var x=0
//func incrament(wg *sync.WaitGroup,m *sync.Mutex){
// // 布置锁
// m.Lock()
// x = x+10
// m.Unlock()
// wg.Done()
// fmt.Println(x) // 从10开始
//
//}
//
//
//func main(){
// var w sync.WaitGroup // 定义变量
// var m sync.Mutex // 定义锁 // 值类型 ,传递地址
// for i:=0;i<1000;i++{
// w.Add(1)
// go incrament(&w,&m)
//
// }
// w.Wait()
// fmt.Println("都执行完毕了",x) // 拿到最后的值
//} // 通过信到实现数据的存值
package main import (
"fmt"
"sync"
)
var x=0
func increment(w *sync.WaitGroup,ch chan bool){
ch<-true // 进行存储
x=x+10
<-ch
w.Done() // 执行
fmt.Println(x,"执行x")
} func main(){
var w sync.WaitGroup // 定义一个
ch :=make(chan bool,1)
for i:=0;i<5;i++{
w.Add(1)
go increment(&w,ch) }
w.Wait()
fmt.Println("final value ofx",x) }
Go语法的基本使用(三)的更多相关文章
- [SQL]SQL语言入门级教材_SQL语法参考手册(三)
SQL 语法参考手册 DB2 提供了关连式资料库的查询语言 SQL (Structured Query Language),是一种非常口语化.既易学又易懂的语法. 此语言几乎是每个资料库系统都必须提供 ...
- C#语法糖系列 —— 第三篇:聊聊闭包的底层玩法
有朋友好奇为什么将 闭包 归于语法糖,这里简单声明下,C# 中的所有闭包最终都会归结于 类 和 方法,为什么这么说,因为 C# 的基因就已经决定了,如果大家了解 CLR 的话应该知道, C#中的类最终 ...
- Java语法糖初探(三)--变长参数
变长参数概念 在Java5 中提供了变长参数(varargs),也就是在方法定义中可以使用个数不确定的参数,对于同一方法可以使用不同个数的参数调用.形如 function(T …args).但是需要明 ...
- Java菜鸟之java基础语法,运算符(三)
赋值运算符 (一)JAVA种的赋值运算符 = ,代表代表的等于,一般的形式是 左边变量名称 = 右边的需要赋的指或者表达式,如果左侧的变量类型级别比较高,就把右侧的数据转换成左侧相同的高 ...
- 常用es5和es6语法区别,以及三个点的用法
链接:https://www.jianshu.com/p/b4d48e9846e7 //三个点 链接:https://blog.csdn.net/qiladuo1207/article/details ...
- C#语法糖之第三篇: 匿名类 & 匿名方法
今天时间有点早,所以上来在写一篇文章吧,继续上一篇的文章,在我们平时编程过程中有没有遇到过这样的一个情景,你定义的类只是用来封装一些相关的数据,但并不需要相关联的方法.事件和其他自定义的功能.同时,这 ...
- 使用INSERT…SELECT语法插入记录(三十二)
前面,我们在谈INSERT语句时,使用两种语句:INSERT…SELECT 和 INSERT…VALUES. INSERT…SELECT可以使用子查询.因为在写SELECT时. *** = ...
- Python2.3-原理之语句和语法
此节来自于<Python学习手册第四版>第三部分 一.python语句简介(第10章) 1.首先记得一个概念:a.程序由模块构成:b.模块包含语句:c.语句包含表达式:d.表达式建立并处理 ...
- Java8初体验(一)lambda表达式语法
感谢同事[天锦]的投稿.投稿请联系 tengfei@ifeve.com 本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人也是刚刚开始学习Java8,所以文中肯定有错误和理解 ...
- 利用Swift之协议语法实现页面间的传值功能
随着Swift 新开发语言的发布,又随着Xcode6.0.1的正式发布,利用swift编写iOS代码迫在眉睫,笔者在使用Objective-C开发近三年以来,对这种优雅的语法深感赞叹,下面我将对比式的 ...
随机推荐
- sklearn3_svc分类器预测
python机器学习-乳腺癌细胞挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003&u ...
- Java语言 List 和 Array 相互转换
Java语言 List 和 Array 相互转换 List集合 转换为 Array数组 List集合 转换成 Array数组,有 2 种方式,代码如下: import java.util.ArrayL ...
- delphi raise 语句: 抛出异常
//例1:begin raise Exception.Create('抛出异常');end;//例2:begin raise Exception.CreateFmt('%s %d', ['错误代码 ...
- Docker学习笔记 — Docker私有仓库搭建
Docker学习笔记 — Docker私有仓库搭建 目录(?)[-] 环境准备 搭建私有仓库 测试 管理仓库中的镜像 查询 删除 Registry V2 和Mavan的管理一样,Dockers ...
- 查看自身公网ip的命令
curl ifconfig.me curl cip.cc curl ipinfo.io
- LeetCode.1137-第N个泰波那契数(N-th Tribonacci Number)
这是小川的第409次更新,第441篇原创 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第260题(顺位题号是1137).Tribonacci(泰波那契)序列Tn定义如下: 对于n&g ...
- 帮助文档 - Wget
(GNU Wget)http://www.gnu.org/software/wget/ 快速浏览(单HTML文件):(GNU Wget 在线手册)http://www.gnu.org/software ...
- 关于torchvision.datasets.CIFAR10
在Pytorch0.4版本的DARTS代码里,有一行代码是 trn_data = datasets.CIFAR10(root=data_path, train=True, download=False ...
- 【机器学习】Jackknife,Bootstraping, bagging, boosting, AdaBoosting, Rand forest 和 gradient boosting
Jackknife,Bootstraping, bagging, boosting, AdaBoosting, Rand forest 和 gradient boosting 这些术语,我经常搞混淆, ...
- MVC、MVP、MVVM模式的概念与区别
1. MVC框架 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示 ...