Java快速转Go入门案例

Golang语言在2009年诞生于谷歌,相较而言是一门年轻的语言。面对C++等老牌语言众多繁重的特性,几名谷歌员工希望能够甩开历史包袱设计一门更加简洁的编程语言,避免过度的设计,通过较少的特性组合连接就可实现复杂的功能。体现“少即是多”设计哲学。

一、Go入门案例

以下是用一个Go实现的栈数据结构

package collection //声明当前代码文件所在的包,相同路径下的Go文件包名必须相同
import "errors" //导入error包,Go中错误只能显式的定义/返回/处理,不能抛出/捕获//结构体struct:类似于Java中的类,但是结构体中只能定义属性,且不存在继承的概念,只有组合和接口
type Stack struct {data []string //切片:类似于Java中的数组,但是Go中切片的大小是可动态扩展的,底层基于数组,更像是Java中的ArrayList
}//函数func:参数前添加*号表示传递引用,不加表示传递数据的副本
func (s *Stack) Push(x string) { //访问权限:Go中函数和变量有两级访问权限,大写字母开头表示包外可访问,小写开头表示只在包内可见,例如Stack中的data变量s.data = append(s.data, x) //append()是Go中的内置函数,可直接调用,用于向切片尾部添加一个元素,并返回新的切片
}//函数支持多重返回值
func (s *Stack) Pop() (string, error) {n := len(s.data) //len()也是内置函数 用于获取切片数组长度if n == 0 {//支持多重赋值r, b := "", errors.New("Pop empty stack error!") //定义一个错误return r, b //函数中定义的变量必须有使用否则会报错}res := s.data[n-1] //:=符号用于快速创建并赋值一个新变量(编译时会自动进行类型推断,Go本身是强类型语言)s.data[n-1] = "" //为了避免内存泄漏s.data = s.data[:n-1] //s.data[:n-1]表示返回对原始数组的一个新的切片视图[0,n-1),不会改变原数组元素return res, nil //nil可表示切片、struct、接口等类型的空值
}//返回栈的大小
func (s *Stack) Size() int {return len(s.data)
}

使用这个栈

package main //main函数只有定义在main包下才可执行import ("HelloGo/collection" //导入collection包"fmt" //Go的标准输入输出包
)//输出: Hello, world!
func main() {var s collection.Stack //var表示声明一个变量pop, err := s.Pop()if err != nil { //if条件可不带括号fmt.Println(pop + err.Error()) //打印错误信息}s.Push("world!") //Go中没有构造器的概念,当声明一个变量而没有明确地初始化时,会自动初始化为默认值s.Push("Hello, ") //对于结构体变量,即内部所有字段初始化为默认值,切片默认为nil表示初始化一个空数组。for s.Size() > 0 {  //故在这里s可以直接使用res, _ := s.Pop() //使用下划线忽略第二个返回值fmt.Print(res)}
}

二、Go的核心特性

  • 跨平台:Go的标准库提供了一系列与操作系统无关的接口和实现,并且Go的编译器本身就具备支持多种操作系统和硬件架构的能力,通过静态链接的方式可直接将程序编译为对应平台的机器码,故Go可以实现跨平台即“一次编写,到处运行”。此外Go还支持交叉编译,即在一个操作系统上编译出适用于另一个操作系统的可执行文件。Go的跨平台由于不需要虚拟机作为中间人,因此更加轻量级,启动和运行更快。
  • 自动内存管理:Go和Java一样,内存是自动分配和回收的。不过目前Go的垃圾回收器相对简单,就是基于三色标记法的非并发GC。
  • 组合与接口:Go通过使用接口和组合而不是继承来实现代码复用。至于Go是不是面向对象,官网的回答是Yes or no,Go既可以通过将函数绑定在结构体上设计出具有面向对象风格的程序,也可以按照面向过程的方式设计和编程。
  • 高性能并发:Go的并发执行单元是协程(gorountine),可看做用户级的线程,由Go在用户层面实现协程任务的调度,协程和内核线程可以是多对一的关系,内核线程是无感知的,可避免过多的线程带来内核调度和上下文切换开销。例如在面对一组IO密集型任务时,普通的多线程在IO阻塞等待时需要挂起让出CPU切换下一个线程,而Go只需要切换下一个协程,内核线程不需要切换。
  • 函数式编程:函数可以像变量一样被赋值、传递、作为返回值。
  • 简洁:语法简洁,语法细节上有许多强制规定,有助于统一代码风格。Go是静态类型并且是强类型的,变量在编译期就确定类型,且不存在类型的隐式转换。

三、语法特性细节

1. 函数类型

函数是Go的一等公民,被赋予了与其他数据类型(如整数、字符串和结构体)相同的地位。

//声明函数类型
type binOp func(int, int) int
//定义函数变量op
var op binOp
//声明并初始化函数变量add
add := func(i, j int) int { return i + j }op = add//赋值
//函数调用
n := op(100, 200)  // n = 100 + 200
2. 并发编程

使用go关键字可直接开启一个协程执行对应函数,channel通道用于在协程间通信

package mainimport ("fmt""time"
)func main() {//内置函数make()用于创建指定初始大小的哈希表、通道、切片等ch := make(chan int, 10) //创建缓冲区大小为10字节的channel通道go func() { //go关键字可直接开启一个协程执行对应函数time.Sleep(time.Second*5)ch <- 123  //在goroutine中向channel发送数据}() //这里定义了一个匿名函数,后面的()为传参val := <-ch  //主goroutine阻塞式从channel接收数据fmt.Println(val)close(ch) //关闭后可读不可写
}

WaitGroup:用于等待一组goroutines的完成。

Mutex:Go中的锁,用于保护共享资源,防止协程同时访问。

package mainimport ("fmt""sync" //并发包
)func main() {var wg sync.WaitGroupvar mu sync.Mutex //独占锁var num intfor i := 1; i <= 5; i++ {wg.Add(1) //增加一个计数go func() {defer wg.Done() //减少一个计数,defer确保函数执行完毕后wg.Done()再执行,类似finally块mu.Lock()   // 获取锁num++       // 修改共享资源mu.Unlock() // 释放锁}()}wg.Wait() // 等待所有goroutine完成,即wg内部计数为0fmt.Println(num) //5
}

Cond:条件等待队列,用于在特定条件下阻塞或唤醒一个或多个goroutines。

3. defer关键字

当在函数中使用 defer 关键字时,它会使后面的函数调用被推迟执行,直到当前函数的执行结束。这意味着无论函数是正常返回还是发生了异常,defer 的函数都会被执行,类似Java中的finally块。如果在同一个函数中多次使用 defer,它们的执行顺序是后进先出(LIFO),也就是最后一个 defer 的函数最先执行,依次类推。

defer语句只会影响其声明位置之后的代码。

4. 错误处理

Go有两种错误处理机制:

  • error:大部分函数返回errors
  • panic:只有真正的不可恢复条件,例如超过范围的索引才会产生真正的运行时异常,称为panic
package mainimport "fmt"func main() {arr := []int{1, 2, 3}defer func() {//if可接受一个初始化语句,该语句通常用于设置局部变量if r := recover(); r != nil { //使用recover函数可捕获panicfmt.Println("发生了运行时错误:", r)}}()for i := 0; i <= 4; i++ {value := arr[i] // 当i=3时数组越界,触发panicfmt.Println("数组元素值:", value)}
}

参考:https://zhuanlan.zhihu.com/p/492270360

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/639096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++面试:跳表

目录 跳表介绍 跳表的特点&#xff1a; 跳表的应用场景&#xff1a; C 代码示例&#xff1a; 跳表的特性 跳表示例 总结 跳表&#xff08;Skip List&#xff09;是一种支持快速搜索、插入和删除的数据结构&#xff0c;具有相对简单的实现和较高的查询性能。下面是跳表…

巨变!如何理解中国发起的“数据要素X”计划?

作者 张群&#xff08;赛联区块链教育首席讲师&#xff0c;工信部赛迪特聘资深专家&#xff0c;CSDN认证业界专家&#xff0c;微软认证专家&#xff0c;多家企业区块链产品顾问&#xff09;关注张群&#xff0c;为您提供一站式区块链技术和方案咨询。 刘烈宏在第25届北大光华新…

自定义shell工具函数之echo_red()和prepare_check_required_pkg()

两个 bash 函数&#xff0c;echo_red 和 prepare_check_required_pkg&#xff0c;它们在 shell 脚本中使用。下面是每个函数的解释&#xff1a; echo_red 函数 function echo_red() {echo -e "\033[1;31m$1\033[0m" }这个函数的目的是输出红色的文本到终端。它接受…

职业规划,软件开发工程师的岗位任职资格

软件工程师是指从事软件开发的人&#xff0c;主要的工作涉及到项目培训和项目设计两个方面。在实际工作中&#xff0c;软件工程师是一个广义的概念&#xff0c;包括了很多与软件相关的人员。除开最基础的编程语言&#xff0c;还有数据库语言等等。从事这份工作&#xff0c;需要…

记录一下uniapp 集成腾讯im特别卡(已解决)

uniapp的项目运行在微信小程序 , 安卓 , ios手机三端 , 之前这个项目集成过im,不过版本太老了,0.x的版本, 现在需要添加客服功能,所以就升级了 由于是二开 , 也为了方便 , 沿用之前的webview嵌套腾讯IM的方案 , 选用uniapp集成ui ,升级之后所有安卓用户反馈点击进去特别卡,几…

【cucumber】学习跟踪

本文章主要跟踪cucumber自动化测试的学习进度&#xff0c;并且统计文章目录&#xff1a; 【cucumber】cluecumber-report-plugin生成测试报告-CSDN博客

openssl3.2 - 官方demo学习 - test - certs - 001 - Primary root: root-cert

文章目录 openssl3.2 - 官方demo学习 - test - certs - 001 - Primary root: root-cert概述笔记官方原版.sh实验自己来分3步走做实验my_openssl_log_001_doc_1.txtmy_openssl_log_001_doc_2.txtmy_openssl_log_001_doc_3.txt备注END openssl3.2 - 官方demo学习 - test - certs …

Java设计模式之观察者模式详解

Java设计模式之观察者模式详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我们将一同深入探讨Java设计模式之观察者模式&#xff0c;这是一种代…

HR人才测评,如何做技术研发人员基本素质测评?

技术研发人员的基本素质测评&#xff0c;可以从以下几个方面考虑&#xff1a; 1. 技术能力&#xff1a;首要的因素是技术能力&#xff0c;包括编程能力、算法能力、架构设计能力、代码调试和优化能力等。在测评中可以通过技术测试、编程练习、项目经验等方式来考察。 2. 学习…

微前端:一种新型的前端架构方法

微前端是一种新型的前端架构方法&#xff0c;它将单页面应用程序拆分为一系列小型、独立的应用程序。本文将介绍微前端的背景、概念、特点、应用场景和与其他前端架构的对比&#xff0c;以帮助读者更好地理解微前端的概念和实践。 一、引言 随着Web应用程序的复杂性和规模不断…

Java - 深入理解加密解密和签名算法

文章目录 应用的接口安全性问题可能来源加密解密Why保护数据隐私防止未经授权的访问防止数据泄露 对称加密 VS 单向加密 VS 非对称加密一、对称加密二、单向加密&#xff08;哈希加密&#xff09;三、非对称加密 常用的对称加密算法1. AES&#xff08;高级加密标准&#xff09;…

Django从入门到精通(二)

目录 三、视图 3.1、文件or文件夹 3.2、相对和绝对导入urls 3.3、视图参数requests 3.4、返回值 3.5、响应头 3.6、FBV和CBV FBV 四、静态资源 4.1、静态文件 4.2、媒体文件 五、模板 5.1、寻找html模板 5.2、模板处理的本质 5.3、常见模板语法 5.4、内置模板函…

【DevOps-08-5】目标服务器准备脚本,并基于Harbor的最终部署

一、简要描述 告知目标服务器拉取哪个镜像判断当前服务器是否正在运行容器,停止并删除如果目标服务器已经存在当前镜像,删除当前版本的镜像目标服务器拉取Harbor上的镜像将拉取下来的镜像运行成容器二、准备目标服务器脚本文件 1、在部署的目标服务器准备deploy.sh部署脚本 …

点云从入门到精通技术详解100篇-基于点云和图像融合的智能驾驶目标检测(中)

目录 2.1.2 数据源选型分析 2.2 环境感知系统分析 2.2.1 传感器布置方案分析

对称密码算法有什么优点

对称密码算法是一种加密和解密数据的方法&#xff0c;其中加密和解密使用相同的密钥。这种方法的一个关键特点是加密和解密的速度非常快&#xff0c;因此它在许多需要高速加密的应用中非常有用。 对称密码算法的优点主要在于其效率和安全性。由于加密和解密使用相同的密钥&…

自定义注解与拦截器实现不规范sql拦截(拦截器实现篇)

最近考虑myBatis中sql语句使用规范的问题&#xff0c;如果漏下条件或者写一些不规范语句会对程序性能造成很大影响。最好的方法就是利用代码进行限制&#xff0c;通过拦截器进行sql格式的判断在自测环节就能找到问题。写了个简单情景下的demo&#xff0c;并通过idea插件来将myB…

UE5 Windows打包时报错“SDK Not Found”解决方案

在Unreal Engine 5.0.3 Windows平台下打包时报错&#xff1a;“Windows的SDK未正常安装&#xff0c;而其是生成数据的必需项。请检查主工具栏中“启动“菜单SDK部分来更新SDK。” 解决方案&#xff1a; 1、打开 Visual Studio Installer&#xff0c;点击“修改”按钮&#xf…

EtherNet/IP开发:C++搭建基础模块,EtherNet/IP源代码

这里是CIP资料的协议层级图&#xff0c;讲解协议构造。 ODVA&#xff08;www.ODVA.org&#xff09;成立于1995年&#xff0c;是一个全球性协会&#xff0c;其成员包括世界领先的自动化公司。结合其成员的支持&#xff0c;ODVA的使命是在工业自动化中推进开放、可互操作的信息和…

到店商详架构变迁

一、项目背景 到店商详是平台为京东到店业务提供的专属商详页面&#xff0c;将传统电商购物路径打造成以LBS门店属性的本地生活服务交易链路。 二、架构变迁 1、 主站商详扩展点 **优点&#xff1a;**到店侧仅关注业务&#xff0c;无需过度关注服务部署、性能优化等。 **缺…

网络安全产品之认识入侵防御系统

由于网络安全威胁的不断演变和增长。随着网络技术的不断发展和普及&#xff0c;网络攻击的种类和数量也在不断增加&#xff0c;给企业和个人带来了巨大的安全风险。传统的防火墙、入侵检测防护体系等安全产品在面对这些威胁时&#xff0c;存在一定的局限性和不足&#xff0c;无…