当前位置: 首页 > 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 

相关文章:

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

目录标题 一、Interface1. Declaring and implementing an interface2. Practical use of an interface3. Nterface internal representation4. Empty interface5. Type assertion6. Type switch7. Implementing interfaces using pointer receivers VS value receivers8. Impl…...

Cesium加载ArcGIS Server4490且orgin -400 400的切片服务

Cesium在使用加载Cesium.ArcGisMapServerImageryProvider加载切片服务时&#xff0c;默认只支持wgs84的4326坐标系&#xff0c;不支持CGCS2000的4490坐标系。 如果是ArcGIS发布的4490坐标系的切片服务&#xff0c;如果原点在orgin X: -180.0Y: 90.0的情况下&#xff0c;我们可…...

Objectarx 2021使用vs2019生成报错 /RTCc rejects conformant code

error C2338: /RTCc rejects conformant code错误解决 使用VS2019/VS2022生成项目报错 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C1189 #error: /RTCc rejects conformant code, so it is not supported by the C Standard Library. Either remove this compiler opti…...

QT中使用QtXlsx库的三种方法 QT基础入门【Excel的操作】

对于Linux用户,如果Qt是通过“ apt-get”之类的软件包管理器工具安装的,请确保已安装Qt5开发软件包qtbase5-private-dev QtXlsx是一个可以读写Excel文件的库。它不需要Microsoft Excel,可以在Qt5支持的任何平台上使用。该库可用于从头开始生成新的.xlsx文件从现有.xlsx文件中…...

容器和云原生(二):Docker容器化技术

目录 Docker容器的使用 Docker容器关键技术 Namespace Cgroups UnionFS Docker容器的使用 首先直观地了解docker如何安装使用&#xff0c;并快速启动mysql服务的&#xff0c;启动时候绑定主机上的3306端口&#xff0c;查找mysql容器的ip&#xff0c;使用mysql -h contain…...

学习总结(TAT)

项目写完了&#xff0c;来写一个总的总结啦&#xff1a; 1.后期错误 Connection&#xff0c;Statement&#xff0c;Prestatement&#xff0c;ResultSet都要记得关闭接口&#xff1b;&#xff08;一定要按顺序关闭&#xff09;&#xff1b; 在写群聊的时候写数据库名的时候不要…...

2023java异常之八股文——面试题

Java异常架构与异常关键字 Java异常简介 Java异常是Java提供的一种识别及响应错误的一致性机制。 Java异常机制可以使程序中异常处理代码和正常业务代码分离&#xff0c;保证程序代码更加优雅&#xff0c;并提高程序健壮性。在有效使用异常的情况下&#xff0c;异常能清晰的…...

数据可视化和数字孪生相互促进的关系

数据可视化和数字孪生是当今数字化时代中备受关注的两大领域&#xff0c;它们在不同层面和领域为我们提供了深入洞察和智能决策的机会&#xff0c;随着两种技术的不断融合发展&#xff0c;很多人会将他们联系在一起&#xff0c;本文就带大家浅谈一下二者之间相爱相杀的关系。 …...

axios使用axiosSource.cancel取消请求后怎么恢复请求,axios取消请求和恢复请求实现

在前端做大文件分片上传&#xff0c;或者其它中断请求时&#xff0c;需要暂停或重新请求&#xff0c;比如这里大文件上传时&#xff0c;可能会需要暂停、继续上传&#xff0c;如下GIF演示&#xff1a; 这里不详细说文件上传的处理和切片细节&#xff0c;后续有时间在出一篇&a…...

SAP动态安全库存简介

动态安全库存:跑需求计划时,ERP系统按设置的库存方式自动计算出满足一定时间内可保障生产的库存数量 SAP动态安全库存的计算公式:动态安全库存=平均日需求*覆盖范围。 平均日需求=特定时期内的总需求/特定时期内的工作天数 覆盖范围指在没又货物供应的情况下,库存可以维…...

JVM基础了解

JVM 是java虚拟机。 作用&#xff1a;运行并管理java源码文件锁生成的Class文件&#xff1b;在不同的操作系统上安装不同的JVM&#xff0c;从而实现了跨平台的保证。一般在安装完JDK或者JRE之后&#xff0c;其中就已经内置了JVM&#xff0c;只需要将Class文件交给JVM即可 写好的…...

QT:event事件分发器,事件过滤器(了解)

Event事件分发器 用于事件的分发 可以用事件分发器做拦截&#xff0c;从而不进入到后面的虚函数中&#xff0c;但是不建议 bool event(QEvent *e); 返回值 如果是true 代表用户处理这个事件&#xff0c;不向下进行分发 e->type&#xff08;&#xff09;中可选择进行拦截的类…...

若依项目的介绍(前后端分离版本)

目录 一、若依介绍 &#xff08;一&#xff09;简单介绍 &#xff08;二&#xff09;若依版本 &#xff08;三&#xff09;Git远程拉取步骤 二、项目的技术介绍 &#xff08;一&#xff09;后端技术 1.spring boot 2.Spring Security安全控制 3.MyBatis 4.MySQL和R…...

DT游乐场建模

丢了一个...

Servlet+JDBC实战开发书店项目讲解第9篇:VIP等级优惠实现

ServletJDBC实战开发书店项目讲解第9篇&#xff1a;VIP等级优惠实现 介绍 在这篇博客中&#xff0c;我们将讲解如何在书店项目中实现VIP等级优惠功能。VIP等级优惠是一种常见的商业策略&#xff0c;可以吸引更多的顾客并提高销售额。我们将使用Servlet和JDBC来实现这个功能。…...

Azure文件共享

什么是Azure文件共享 Azure文件共享是一种在云中存储和访问文件的服务。它允许用户在不同的计算机、虚拟机和服务之间共享数据&#xff0c;并在应用程序中进行访问、修改和管理。 Azure文件共享可以用于各种用途&#xff0c;例如&#xff1a; 共享文件资源给多个虚拟机或服务…...

idea新建web项目

步骤一 步骤二 步骤三 新建两个目录lib、classes 步骤四 设置两个目录的功能lib、classes 步骤五 发布到tomcat...

回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效…...

电商增强现实3D模型优化需要关注的4个方面

到目前为止&#xff0c;AR技术已经发展到足以在更广泛的范围内实施。 在电子商务中&#xff0c;这项技术有望提供更令人兴奋的购物体验。 为了实现这一目标&#xff0c;在这篇博客中&#xff0c;我将介绍如何针对电子商务中的 AR 优化 3D 模型。 推荐&#xff1a;用 NSDT编辑器…...

【Effective Python】读书笔记-04推导与生成

1. 用列表推导取代 map 与 filter 因为不需要写 lambda 表达式。 可以很容易地跳过原列表中的某些数据。 # 列表推导l [i for i in range(5)] # [0, 1, 2, 3, 4] print(l)# 字典推导d {i: i ** 2 for i in range(5)} # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} print(d)2. 控制推导…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...