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开发近三年以来,对这种优雅的语法深感赞叹,下面我将对比式的 ...
随机推荐
- LoadRunner 技巧之 思考时间设置
LoadRunner 技巧之 思考时间设置 用户访问某个网站或软件,一般不会不停地做个各种操作,例如一次查询,用户需要时间查看查询的结果是否是自己想要的.例如一次订单提交,用户需要时间核对自己填写的信 ...
- visual studio 2019不能在vue文件中直接识别less语法
试了好多方法,不象vs code那样能直接在template vue文件中就识别less语法下边这种分离的方式是可以的,在项目中也比较实用,将来你代码量大了,样式/脚本也还是要和template代码分 ...
- 用泛型方法Java从实体中提取属性值,以及在泛型方法中的使用
public <T> T getFieldValue(Object target, String fieldName, Class<T> typeName) { try { O ...
- 【转】Java从hdfs上读取文件中的某一行
[From]https://blog.csdn.net/u010989078/article/details/51790166 package test; import java.io.Buffere ...
- SqlServer:SqlServer(数据库备份,数据文件迁移,增加数据库文件组,递归查询一周报送情况,查询近X天未报送单位,截断数据库日志,复制单个或多个数据库表到另一个数据库 )
1.数据备份 ) ) ) )),'-','') ) SET @savePath = 'f:/DatabaseBackup/' DECLARE My_Cursor CURSOR FOR ( select ...
- 安卓渗透测试工具——Drozer(安装和使用)
移动端渗透测试工具相比丰富的web端真的是少之又少,最近在做app的安全测试,用到了drozer,drozer的安装过程真的是太心酸了,中间报错了有6次才成功安装.. 一.环境准备 首先准备以下环境: ...
- 云计算共享组件--时间同步服务NTP(2)
一.标准时间讲解 地球分为东西十二个区域,共计 24 个时区 格林威治作为全球标准时间即 (GMT 时间 ),东时区以格林威治时区进行加,而西时区则为减. 地球的轨道并非正圆,在加上自转速度逐年递减, ...
- 色彩空间RGB/CMYK/HSL/HSB/HSV/Lab/YUV基础理论及转换方法:RGB与YUV
之前做个设计,现在从事IT,脑子里面关于RGB,RGBA,CMY,CMYK,YUV,但是具体理论还是不扎实.若干年前之前写过<水煮RGB与CMYK色彩模型—色彩与光学相关物理理论浅叙>&l ...
- python random 的用法
python random的里面的方法其实是Random实例化的对象. 里面几个常用的几个方import random print( random.randint(1,10) ) # 产生 1 到 1 ...
- Lombok的使用与原理
在面向对象编程中必不可少需要在代码中定义对象模型,而在基于Java的业务平台开发实践中尤其如此.相信大家在平时开发中也深有感触,本来是没有多少代码开发量的,但是因为定义的业务模型对象比较多,而 ...