Go 语言入门指南:基础语法和常用特性解析| 青训营

115 阅读7分钟

前言

作为后端的两大语言, Go与Java是每一位想在将来从事后端工作所必须要掌握的语言,借此夏令营的契机,自己也学一下Go语言。因为自己先前基本用的都是Java和Python,因此也想把Go和Java做一些对比学习

Go语言基础语法

行分隔符

在Go中,一行代表一个语句的结束,很像Python,不像Java一样需要;结尾

字符串连接

Go语言的字符串连接可以通过+实现:

fmt.Println("hello" + "BB")  

而在Java中,我们也可以通过+的形式连接字符串,不过,我个人还是喜欢用Stringbuffer来进行字符串的操作:

System.out.println("hello" + "bb");  
StringBuffer sb = new StringBuffer("hello");  
sb.append("bb");  

Go语言的空格使用

这点和Java以及Python都是类似的,在变量声明/逻辑运算中间添加空格,可以提高代码的可读性

格式化字符串

Go中的格式化字符串主要有fmt.Sprintf 或 fmt.Printf,操作如下:

var s1 = "hello"  
var s2 = "my"  
var s3 = "bb"  
var url = fmt.Sprintf(s1, s2, s3)  
fmt.Println(url)

而在Java中,我们则一般通过System.out.printf的方式进行操作

函数定义

Go语言中的函数定义,给我的感觉是更像Python 例如,我们想定义一个计算最大值得max()函数,那么,函数定义如下:

func max(num1, num2 int) int{}

func打头定义函数,然后max是函数名,参数列表表示int类型的num1和num2,然后返回值是int类型 而在Java中,我们一般这样写:

public int max(int num1,int num2){}

我们首先定义函数的权限,然后是返回值的类型,最后是参数列表

诶?难道Go中没有声明权限吗?不对,这不符合我们面向对象开发、在工程中开发的逻辑呀

其实,Go语言的访问控制通过命名约定和包的方式来实现的,而不是通过权限修饰符

如果你在一个包中定义了一个函数,以大写字母开头,那么该函数就是导出的,可以在其他包中调用。如果函数以小写 字母开头,那么它只能在同一个包中访问,对其他包是不可见的

例如,有如下定义的两个函数:

func ExportedFunction() {  ... }
func notExportedFunction() {  ... }

那么,我们在其他包中,可以使用ExportedFunction方法,但是notExportedFunction却是不可用的

数组

数组作为一个最为基本的数据结构,在Go语言中的定义如下:

var numbers [5]int
var numbers [5]int{1,2,3,4,5}
numbers := [5]int{1,2,3,4,5}

比Java的数组定义方式要简单许多,根据我平时的学习发现,第三种第一方式应该是使用最多的

通过var来进行定义,Java中也出现过,这里也回忆一下

在 Java 中,var 是从 Java 10 开始引入的一种局部变量类型推断的关键字。它可以用于声明局部变量,但不能用于声明成员变量、方法参数、返回类型或类字段,使用方式如下:

var numbers = List.of(1, 2, 3, 4, 5);

写起来是很方便的,为什么Java中也要用var呢,使用 var 关键字的主要目的是为了简化代码并提高可读性。通过类型推断,编译器可以根据初始化表达式的类型自动推断出变量的类型,从而减少了重复的类型声明。这在一些情况下可以使代码更加清晰简洁,特别是在初始化表达式的类型显而易见的情况下。

emmm,但是过多的写又会降低代码的可读性,只能写在功能比较明了的函数中

指针

我们先回忆一下Java中的指针,说实话,感觉指针一直是一种比较高级的变量,感觉上C/C++为用户完全开放指针的方式,就已经在一定程度上使得C更贴近计算机的底层逻辑了

在Java中,我们new一个对象,本身也是返回一个内存中对象的引用,而我们访问一块为null的对象时,也直接会抛出一个空指针异常(NullPointerException)错误

在 Java 中并没有直接的指针操作,而是通过引用来操作对象。这种设计减少了许多内存管理问题和悬空指针访问的风险,使得 Java 更加安全和可靠

而在Go中,我们通过如下方式来定义指针

var ip *int
var fp *float32

在指针类型前面加上 * 号(前缀)来获取指针所指向的内容

而我们也可以很方便地定义一个空指针,当一个指针被定义后没有分配到任何变量时,它的值为 nil,也就是空指针

空指针和Java中的null类似,但是判断时,要注意改成nil哦,示例代码如下:

if(ptr != nil) 

Go语言特性

高并发机制

首先肯定是Go语言在高平发场景中的优异表现,这其实也是我们常说的Go面向大厂的原因之一吧,虽然高平发一定会在企业中越来越重要,但是目前能用高并发的确实是大厂多一些

对比来讲,Go语言天生支持并发,通过Goroutines和通道实现高并发任务的编写非常方便,适合于处理大规模的高并发场景,如网络编程、服务器等。 Java虽然也支持高并发,但相对于Go语言来说,使用线程进行并发编程相对繁琐,需要更多的同步和线程管理操作。Java在高并发场景下需要更多的开发工作和资源来保证稳定性和性能

GC机制

垃圾回收(GC)机制,在每个语言中都有,PS:今天还因为在Python里没有删除干净钩子而爆了内存

而在Java和Go中,两者都需手动释放内存,两者都使用自动垃圾回收机制来管理内存,减轻了开发人员的负担,防止内存泄漏

同时,两者都采用分代垃圾回收策略,即将对象分为不同的代,根据对象的存活时间和使用情况进行回收

最后,Go语言和Java都支持并发垃圾回收,可以在程序运行时进行垃圾回收操作,而不会阻塞主线程的执行

相比Java,Go语言的内存模型更为轻量级,使用了类似指针的数据结构,通过指针可以避免内存拷贝,同时也有助于减少GC的负担。Java的内存模型相对复杂一些

Go语言的GC算法采用了三色标记清除算法,并引入了并发标记和并发清除,从而在一定程度上减小了GC的停顿时间G。Java的GC算法有很多种,包括标记-清除、标记-整理、复制等

在Java中,可以通过配置不同的垃圾回收器和参数来调整GC的行为。而Go语言的GC是内置在语言中的,不同版本的Go语言会有一些GC相关的参数可以调整,但整体上比Java的配置选项要少

总体来说,Go语言的GC性能通常较高,尤其在处理大规模并发的情况下表现出色。Java的GC性能也不错,但在一些极端情况下可能需要更多的调优和配置,也就是我们常说的:调优

End

笔记先计这么多,在学习了C/C++/Java/Python/JavaScript后,Go的上手并不难,后续将Go的所学用到项目中才是关键!