当前位置: 首页 > news >正文

Go语言基础:Interface接口、Goroutines线程、Channels通道详细案例教程

目录标题

  • 一、Interface
    • 1. Declaring and implementing an interface
    • 2. Practical use of an interface
    • 3. Nterface internal representation
    • 4. Empty interface
    • 5. Type assertion
    • 6. Type switch
    • 7. Implementing interfaces using pointer receivers VS value receivers
    • 8. Implementing multiple interfaces
    • 9. Embedding interfaces
    • 10. Zero value of Interface
  • 二、Goroutines
    • 1. How to start a Goroutine?
    • 2. Starting multiple Goroutines
  • 三、Channels
    • 1. Declaring channels
    • 2. Channel example program
    • 3. Another example for channels
    • 4. Deadlock
    • 5. Unidirectional channels
    • 6. Closing channels and for range loops on channels

一、Interface

1. Declaring and implementing an interface

        package mainimport "fmt"type VowelsFinder interface {FindVowels() []rune}type MyString stringfunc (ms MyString) FindVowels() []rune {var vowels []runefor _, rune := range ms {if rune == 'a' || rune == 'e' || rune == 'i' || rune == 'o' || rune == 'u' {vowels = append(vowels, rune)}}return vowels}func main() {name := MyString("LiangXiaoQing")var v VowelsFinderv = namefmt.Printf("vowels are %c", v.FindVowels())}// vowels are [i a i a o i]

2. Practical use of an interface

        type SalaryCalculator interface {CalculateSalary() int}type Permanent struct {empId    intbasicapy intpf       int}type Contract struct {empId    intbasicapy int}type Freelancer struct {empId       intratePerHour inttotalHours  int}func (p Permanent) CalculateSalary() int {return p.basicapy + p.pf}func (c Contract) CalculateSalary() int {return c.basicapy}func (f Freelancer) CalculateSalary() int {return f.ratePerHour * f.totalHours}func totalExpense(s []SalaryCalculator) {expense := 0for _, v := range s {expense = expense + v.CalculateSalary()		// 循环添加每个值}fmt.Printf("Total Expense Per Month $%d", expense)}func main() {p1 := Permanent{empId:    1,basicapy: 4999,pf:       10,}p2 := Permanent{empId:    2,basicapy: 5999,pf:       20,}c1 := Contract{empId:    3,basicapy: 3000,}f1 := Freelancer{empId:       4,ratePerHour: 77,totalHours:  666,}f2 := Freelancer{empId:       5,ratePerHour: 66,totalHours:  111,}employees := []SalaryCalculator{p1, p2, c1, f1, f2}fmt.Println(employees)totalExpense(employees)}// [{1 4999 10} {2 5999 20} {3 3000} {4 77 666} {5 66 111}]// Total Expense Per Month $72636

3. Nterface internal representation

        type Worker interface {Work()}type Person struct {name string}func (p Person) Work() {fmt.Println(p.name, "is Working")}func describe(w Worker) {fmt.Printf("Interface type %T value %v\n", w, w)}func main() {p := Person{name: "Like",}var w Worker = pdescribe(w)w.Work()}// Interface type main.Person value {Like}// Like is Working

4. Empty interface

        func describe(i interface{}) {fmt.Printf("type = %T, value= %v\n", i, i)}func main() {s := "Hello World"describe(s)i := 55describe(i)strt := struct {name string}{name: "Like",}describe(strt)}// type = string, value= Hello World// type = int, value= 55// type = struct { name string }, value= {Like}

5. Type assertion

        func assert(i interface{}) {s := i.(int)fmt.Println(s)//v, s := i.(int)//fmt.Println(v, s) // 56, true 如果是两个值 则是值和true or false}func main() {var i interface{} = 56assert(i) // 56var s interface{} = "Like"assert(s) // panic: interface conversion: interface {} is string, not int}

6. Type switch

        func findType(i interface{}) {switch i.(type) {case string:fmt.Printf("I am string and my value is %s\n", i.(string))case int:fmt.Printf("I am an int and my value is %d\n", i.(int))default:fmt.Printf("Unknown type\n")}}func main() {findType("Like")findType(666)findType(66.99)}// I am string and my value is Like// I am an int and my value is 666// Unknown type

7. Implementing interfaces using pointer receivers VS value receivers

        package mainimport "fmt"type Describer interface {Describe()}type Person struct {name stringage  int}type Address struct {state   stringcountry string}func (p Person) Describe() {fmt.Printf("%s is %d years old\n", p.name, p.age)}func (a *Address) Describe() {fmt.Printf("State %s Counrty %s", a.state, a.country)}func main() {var d1 Describerp1 := Person{"Like", 11}d1 = p1d1.Describe() // Like is 11 years oldp2 := Person{"Jack", 22}d1 = &p2      //{Jack 22}d1.Describe() // Jack is 22 years oldvar d2 Describera := Address{"LiangXiaoXiao", "China"}d2 = &ad2.Describe() // State LiangXiaoXiao Counrty China}// Like is 11 years old// Jack is 22 years old// State LiangXiaoXiao Counrty China`

8. Implementing multiple interfaces

        type SalaryCalculators interface {DisplaySalary()}type LeaveCalculator interface {CalculateLeavesLeft() int}type Employee struct {firstName   stringlastName    stringbasicPay    intpf          inttotalLeaves intleavesTaken int}func (e Employee) DisplaySalary() {fmt.Printf("%s %s has salary $%d", e.firstName, e.lastName, (e.basicPay + e.pf))}func (e Employee) CalculateLeavesLeft() int {return e.totalLeaves - e.leavesTaken}func main() {e := Employee{firstName:   "Naveen",lastName:    "Ramanathan",basicPay:    5000,pf:          200,totalLeaves: 30,leavesTaken: 5,}var s SalaryCalculators = es.DisplaySalary()var l LeaveCalculator = efmt.Println("\nLeaves left =", l.CalculateLeavesLeft())}// Naveen Ramanathan has salary $5200// Leaves left = 25

9. Embedding interfaces

        type SalaryCalculators interface {DisplaySalary()}type LeaveCalculator interface {CalculateLeavesLeft() int}type EmployeeOperations interface {SalaryCalculatorsLeaveCalculator}type Employee struct {firstName   stringlastName    stringbasicPay    intpf          inttotalLeaves intleavesTaken int}func (e Employee) DisplaySalary() {fmt.Printf("%s %s has salary $%d", e.firstName, e.lastName, (e.basicPay + e.pf))}func (e Employee) CalculateLeavesLeft() int {return e.totalLeaves - e.leavesTaken}func main() {e := Employee{firstName:   "Naveen",lastName:    "Ramanathan",basicPay:    5000,pf:          200,totalLeaves: 30,leavesTaken: 5,}var s EmployeeOperations = es.DisplaySalary()fmt.Println("\nLeaves left =", s.CalculateLeavesLeft())}// Naveen Ramanathan has salary $5200// Leaves left = 25

10. Zero value of Interface

        package mainimport "fmt"type Describer interface {  Describe()}func main() {  var d1 Describerif d1 == nil {fmt.Printf("d1 is nil and has type %T value %v\n", d1, d1)}}// d1 is nil and has type <nil> value <nil> 

二、Goroutines

1. How to start a Goroutine?

        package mainimport ("fmt""time")func hello() {fmt.Println("Hello world goroutine")}func main() {go hello()                  // 没有等待完成就下一步了time.Sleep(1 * time.Second) // 优化添加io操作 则看见了运行hello的输入fmt.Println("main function")}

2. Starting multiple Goroutines

        package mainimport (  "fmt""time")func numbers() {  for i := 1; i <= 5; i++ {time.Sleep(250 * time.Millisecond)fmt.Printf("%d ", i)}}func alphabets() {  for i := 'a'; i <= 'e'; i++ {time.Sleep(400 * time.Millisecond)fmt.Printf("%c ", i)}}func main() {  go numbers()go alphabets()time.Sleep(3000 * time.Millisecond)fmt.Println("main terminated")}// 1a23b4c5deMain Terminated

三、Channels

1. Declaring channels

        package mainimport "fmt"func main() {var a chan intif a == nil {fmt.Println("Channel a is nil, going to define it")a = make(chan int)fmt.Printf("Type of a is %T", a)}}// Channel a is nil, going to define it// Type of a is chan int

2. Channel example program

        package mainimport ("fmt""time")func hello(done chan bool) {fmt.Println("Hello go routine is going to sleep")time.Sleep(4 * time.Second)fmt.Println("hello go routine awake and going to write to done")done <- true // 将 true发送给done通道 表示hello结束运行}func main() {done := make(chan bool) // 创建done通道 bool类型fmt.Println("Main going to call hello go goroutine")go hello(done) // 启动goroutine线程并发 不会阻塞主线程 运行hello<-done         //  done 通道接收数据 阻塞操作 直到接收到数据为止 hello发送了true解除阻塞time.Sleep(1 * time.Second)fmt.Println("Main received data")}// Main going to call hello go goroutine// Hello go routine is going to sleep// hello go routine awake and going to write to done// Main received data

3. Another example for channels

        package mainimport (  "fmt")func calcSquares(number int, squareop chan int) {  sum := 0for number != 0 {digit := number % 10sum += digit * digitnumber /= 10}squareop <- sum}func calcCubes(number int, cubeop chan int) {  sum := 0 for number != 0 {digit := number % 10sum += digit * digit * digitnumber /= 10}cubeop <- sum} func main() {  number := 589sqrch := make(chan int)cubech := make(chan int)go calcSquares(number, sqrch)go calcCubes(number, cubech)squares, cubes := <-sqrch, <-cubechfmt.Println("Final output", squares + cubes)}// Final output 1536  

4. Deadlock

        package mainfunc main() {  ch := make(chan int)ch <- 5}// fatal error: all goroutines are asleep - deadlock!// goroutine 1 [chan send]:// main.main()//        D:/one/channel.go:34 +0x31

5. Unidirectional channels

        func sendData(sendch chan<- int) {sendch <- 10}func main() {chnl := make(chan int)go sendData(chnl)fmt.Println(<-chnl) // 接收数据 并打印}// 10

6. Closing channels and for range loops on channels

        func producer(chnl chan int) {for i := 0; i < 10; i++ {chnl <- i}close(chnl)}func main() {ch := make(chan int)go producer(ch)for {v, ok := <-chfmt.Println(v, ok)if ok == false {break}fmt.Println("Received", v, ok)}}// Received  0 true  // Received  1 true  // Received  2 true  // Received  3 true  // Received  4 true  // Received  5 true  // Received  6 true  // Received  7 true  // Received  8 true  // Received  9 true 
http://www.lryc.cn/news/131921.html

相关文章:

  • Cesium加载ArcGIS Server4490且orgin -400 400的切片服务
  • Objectarx 2021使用vs2019生成报错 /RTCc rejects conformant code
  • QT中使用QtXlsx库的三种方法 QT基础入门【Excel的操作】
  • 容器和云原生(二):Docker容器化技术
  • 学习总结(TAT)
  • 2023java异常之八股文——面试题
  • 数据可视化和数字孪生相互促进的关系
  • axios使用axiosSource.cancel取消请求后怎么恢复请求,axios取消请求和恢复请求实现
  • SAP动态安全库存简介
  • JVM基础了解
  • QT:event事件分发器,事件过滤器(了解)
  • 若依项目的介绍(前后端分离版本)
  • DT游乐场建模
  • Servlet+JDBC实战开发书店项目讲解第9篇:VIP等级优惠实现
  • Azure文件共享
  • idea新建web项目
  • 回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测(多指标,多图)
  • 电商增强现实3D模型优化需要关注的4个方面
  • 【Effective Python】读书笔记-04推导与生成
  • Android内存泄漏总结和性能优化技巧
  • leetcode 125.验证回文串
  • ZooKeeper客户端使用与经典应用场景
  • 标签准备——labelIMG工具使用——自动化标注
  • 关于vant2 组件van-dropdown-item,在IOS手机上,特定条件下无法点击问题的探讨
  • 一零七一、Spring大海捞针篇
  • 请求并发控制
  • 创建密码库/创建用户帐户/更新 Ansible 库的密钥/ 配置cron作业
  • vue实现穿梭框,ctrl多选,shift多选
  • Win11中zookeeper的下载与安装
  • ubuntu22.04 找不到串口,串口ttyusb时断时续的问题(拔插以后能检测到,过会儿就检测不到了)