美文网首页
一名Java开发的Go语言学习笔记(一)

一名Java开发的Go语言学习笔记(一)

作者: 泊浮目 | 来源:发表于2023-05-15 09:48 被阅读0次
版本 日期 备注
1.0 2023.5.15 文章首发

本文首发于泊浮目的掘金:https://juejin.cn/user/1468603264665335

0. 概要

最近因为业务需要在学Go语言,虽然之前也用过别的语言,但主力语言一直是Java。在这里也想主要想用Java做对比,写几篇笔记。

这篇主要是讲语言本身及较为表面的一些对比。

这里的对比用的是Java8,Go的版本是1.20.2。

1. Compile与Runtime

  • 在静态、动态链接支持方面,两者相同。
  • Go在Runtime时,程序结构是封闭的。但Java并不是,基于Classloader的动态加载,实现许多灵活的特性,比如Spring,FlinkSQL。但这样做会让Java应用的Startup时间更长。
  • Java的Runtime久经打磨,也是面向长时间应用设计。
  • Go直接编译成可执行文件,而Java是先编译成Class文件,然后JVM去解释执行。

有兴趣的同学可以看我之前的的一篇笔记:《笔记:追随云原生的Java》

2. 命名规范

  • Go语言在变量命名规范遵循的是C语言风格,越简单越好。
  • Java建议遵循见名知意。
  • 比如:
    • 下标:Java建议index,Go建议i
    • 值:Java建议value,Go建议v
  • 我认为语言上偏简单的设计,则对工程师的能力要求更强。

3. 标准库对于工程能力的支持

  • 无论是Format还是Test以及模块管理,Go都是开箱即用的,比较舒服。如果标准库的确很好用、社区的迭代能力强,那这是个好事,现在看来就是。
  • Java对于这块都是经过了长期的发展,相关的工具链比较成熟,相当于是物竞天择留下来的。

4. Composite litera(复合字面值)

可能没人听过这个说法,举几个例子:

m := map[int]string {1:"hello", 2:"gopher", 3:"!"}

复合字面值由两部分组成:一部分是类型,比如上述示例代码中赋值操作符右侧的map[int]string;另一部分是由大括号{}包裹的字面值。

在声明对象时,也有类似的用法:

// $GOROOT/src/net/http/transport.go
var DefaultTransport RoundTripper = &Transport{
    Proxy: ProxyFromEnvironment,
    DialContext: (&net.Dialer{
        Timeout:   30 * time.Second,
        KeepAlive: 30 * time.Second,
        DualStack: true,
    }).DialContext,
    MaxIdleConns:          100,
    IdleConnTimeout:       90 * time.Second,
    TLSHandshakeTimeout:   10 * time.Second,
    ExpectContinueTimeout: 1 * time.Second,
}
 

Go推荐使用field:value的复合字面值形式对struct类型变量进行值构造,这种值构造方式可以降低结构体类型使用者与结构体类型设计者之间的耦合,这也是Go语言的惯用法。

这个是真的很香,Groovy和Kotlin也有类似的支持,很方便使用。尤其是构造函数特别长的时候,你可能说builder也可以做到,但谁不想少写几行代码呢。

5. 对于编程范式的支持

  • 在Java中,类是一等公民。支持继承、组合,对函数式编程有一定的支持。
  • 在Go中,函数是一等公民(多返回值),对于函数式编程支持较为完备。对面向对象完全通过组合来实现。
  • 从传参是否可以传函数上,我们就可以看出Go的支持比Java好。Java传参中,传一个函数,其实是通过一个匿名对象来传,而Go是真正的一个函数。Kotlin在这块相对Java好了点,至少在编写时。
  • 在Java中,你想写个工具函数,也要先声明一个类再写进去。略Verbose,其实这个类我们不会把它new出来,只是为了放个函数,所以我们写了个类。但实际用的时候,XxxUtils.method,前面的Xxx其实有一定的提醒作用,可以作为一个上下文来猜测里面的逻辑。但是如果我们在method里写清楚,当然也可以做到同样的功效,所以这点来说Go是比较舒服的。
  • Go的对象方法声明方式比较特殊:
//声明一个类型
type MyInt int
//绑定一个方法
//func后面的()里,相当于声明了这个方法绑定的类型。在Go语言里叫做recevier,一个函数只能有一个recevier,且不能是指针、接口类型。
//不能横跨Go包为其他包内的自定义类型定义方法。
func (i MyInt) String() string {
    return fmt.Sprintf("%d", int(i))
}
//在编译期,会把方法的第一个参数变成recevier。很简单的实现。有点像Koltin中的Extension Properties。
  • Go的Interface是隐式的,只要你实现了对应的方法,就是这个Interface的实现。这个在一开始使用的时候会很不适应,但这个松耦的一种体现——隐式的interface实现会不经意间满足依赖抽象、里氏替换、接口隔离等设计原则。
  • Go并没有继承。类似的做法叫做类型嵌入(type embedding)的方式。简单来说就是你有一个T1,T2类型,他们有各自的方法,当你声明一个T类型时并包含了T1,T2类型的field,那么T就拥有了T1,T2的方法。这个实现的确比继承舒服多了,继承很容易写出一些坏味道的代码。这是一种委派思想的实现(delegate)。JS中原型链从外表看起来也有点像这种。
  • Go的方式支持多返回值。这点是比较舒服的,如果在Java中要返回多个值,就要考虑封装成对象了,比如Tuple2,Tuple3...之类的,这在其他的一些JVM语言中随处可见。

6. 异常流:Error与Exception

  • Go里面的error相当于Java的可检异常,Panic相当于Java的RuntimeException和Error。
  • 如果你觉得Go里面大量的if err != nil让代码嵌套时,可以看看一些优化if else的技巧,比如我博客里有。
  • 总的来说,像是在不同的实现做同一件事。也是个仁者见仁智者见智的事。

7. 并发

  • Java用的POSIX原语义的线程。而Go是自己实现了一套用户态的线程,或者说叫协程。
  • POSIX原语义的线程总体来说易用性没这么好,需要牢记一些知识点才可以避免踩坑。Go在这点上比较友好。
  • 性能上,由于实践时一般Java会用线程池,所以创建、销毁的代价还好。其实Go也有自己的线程池,用线程去绑多个协程。但在上下文切换上,的确是POSIX原语义的线程代价会大点。
  • 为了避免一个协程把线程独占住,在编译期、以及一些标准库API上都要做缜密的设计。

相关文章

  • 笨办法学golang(三)

    这是Go语言学习笔记第三篇。 Go语言学习笔记参考书籍「Go语言圣经」以及Go官方标准库 Go语言基本类型主要有布...

  • 笨办法学golang(四)

    这是Go语言学习笔记的第四篇 Go语言学习笔记参考书籍「Go语言圣经」以及Go官方标准库 数组 数组是指一系列同类...

  • Kotlin - 关键字与操作符

    作为一名Android开发人员,一直都使用Java语言进行App开发。不过在Google I/O 2017中,Go...

  • 笨办法学golang(二)

    这是Go语言学习笔记的第二篇文章。 Go语言学习笔记参考书籍「Go语言编程」、Go官方标准库 前文提要 上篇文章中...

  • Golang 学习笔记(01)—— 基础

    本文为转载,原文:Golang 学习笔记(01)—— 基础 Golang介绍 Go语言是由Google开发的一个开...

  • 2.教你打造最简比特币之工作量证明

    开发语言:Go语言 本教程是学习Jeiwan的博客后的学习笔记,代码实现也参考它的为主,精简了叙述并在适当位置添加...

  • 4.教你打造最简比特币之交易

    开发语言:Go语言 本教程是学习Jeiwan的博客后的学习笔记,代码实现也参考它的为主,精简了叙述并在适当位置添加...

  • 服务器后端开发,学什么编程语言?#技术#

    后台开发,目前主流的编程语言是Java,Go语言,C++,python 以及php 。 个人建议学Java,主流中...

  • Go语言实战笔记

    Go语言实战笔记(二)| Go开发工具https://www.flysnow.org/2017/03/08/go-...

  • java之后 对go的学习

    java目前工作的语言 鉴于python, go 的趋势 区块链中 go 学习go语言,尝试不同的风格,以及实际的...

网友评论

      本文标题:一名Java开发的Go语言学习笔记(一)

      本文链接:https://www.haomeiwen.com/subject/qyymsdtx.html