社区编辑申请
注册/登录
为 Java 开发者准备的 Go 教程之Java 有而 Go 无
开发 后端
Go 语言的设计是站在巨人的肩膀上的,它吸取了其他语言的优秀设计,同时摒弃了一些「不认可」的设计。同时,为了保持简单性,Go 的特性也比很多其他语言少。因此,Java 有一些特性,Go 没有。但没有,不代表不好。

大家好,我是 polarisxu。

Go 语言的设计是站在巨人的肩膀上的,它吸取了其他语言的优秀设计,同时摒弃了一些「不认可」的设计。同时,为了保持简单性,Go 的特性也比很多其他语言少。因此,Java 有一些特性,Go 没有。但没有,不代表不好。本文就看看具体有哪些。(当然,也存在 Go 有的特性,而 Java 没有)

1、多重赋值

Java 可以在一条语句中将同一个值分配给多个变量(很多 C 族语言都支持)。例如:

  1. int x, y, z; 
  2. x = y = z = 10; 

Go 不支持上面的语法。相反,Go 采用另一种形式,有些时候更简便。

  1. var x, y, z int = 10, 10, 10 

而且,可以是不同类型:

  1. var x, y, z = 10, 12.0, "polarisxu" 

正因为有这样的语法,在 Go 中交换两个变量的值很方便,不需要引入中间变量:

  1. var x, y = 1, 2 
  2.  
  3. x, y = y, x 

2、语句和运算符

Go 和 Java 运算符具有不同的优先级。Go 的优先级更少,在我看来这更自然。如果不确定,请明确使用括号来指定优先级。一般来说,大家不用刻意去记这些优先级,有一个大概的印象即可。

但有一个关键的区别要记住,在 Go 中,i++ 和 i-- 是语句,而不是表达式。这是什么意思呢?语句就表明不能出现这样恶心的写法(常见的恶心面试题):

  1. // Go 中非法 
  2. x = i++ + y 

而且,Go 中根本没有 --i 或 ++i。而 Java 是支持的。

Go 还不支持三元表达式。需要使用 if/else 语句代替。这点遭到很多人吐槽,毕竟大部分语言都支持。

  1. // Go 中编译不通过 
  2. z := x > y ? x : y 
  3.  
  4. // 得改为类似这样: 
  5. var z = y 
  6. if x > y { 
  7.   z = x 

3、Assert 语句

Go 没有 assert(断言)语句。不过 Go 单元测试挺不错的,一般会用测试来做类似的事情,而且也有一些好的测试框架支持 assert。在写 Demo 时,经常 err != nil 时,倾向于用 panic 来中断程序,不过正式代码建议少用 panic。

4、While 和 Do 语句

while、do、for 是大部分语言提供的三大循环关键字。然而,Go 认为没必要搞这么多关键字,直接一个 for 搞定。(虽然没有直接替换 do 语句的,但肯定可以用 for 搞定)

  1. // 相当于 while (true) {} 
  2. for {} 
  3.  
  4. // 相当于 while (x < 1) {} 
  5. for x < 1 {} 
  6.  
  7. // ... 

注意,Go 中的条件,包括 if 语句的,小括号可以省略,而且没有纠结的 { 到底放在哪的问题,规定了只能放在末尾。

5、Throw 语句

Go 没有 try/catch,因此也没有 throw。硬要找一个类似的,那就是 panic,但思想是不一样的。

6、Java 的一堆修饰符,Go 都没有

比如 strictfp, transient, volatile, synchronized, abstract, static,这些关键字,Go 都没有,也没有类似的。大多数都是不需要的,因为 Java 中需要它们的问题在 Go 中以不同的方式得到解决。例如,通过将变量声明为 package 级来实现与静态值类似的效果。

7、对象、类、内部类、构造函数、this、super 等

Go 不像 Java 那样完全支持面向对象编程(OOP)。因此,它不支持这些 Java 结构。但 Go 不少功能可以与大多数 OOP 功能类似使用,后续文章会讲解。因此,Go 最好被描述为一种基于对象的语言。Go 允许实现 OOP 的一些关键目标,但与严格的 OOP 语言通常所采用的方式不同。最主要的是 Go 不支持继承(虽然可以模拟类似继承的功能),强调使用组合,因为继承有点被乱用了。

Go 不支持类,也没有构造函数(一般通过实现一个普通 New 函数充当构造函数),但有类似的功能,比如支持为类型定义方法,支持实现接口等。Go 的类型嵌套是组合,勉强有点类似 Java 的内部类。

Go 不需要显示声明实现哪个接口,而是一种隐式实现,大家通常称为 duck type。

Go 没有 this、super 等关键字。

8、函数式编程

虽然 Go 一开始就将函数定义为一等公民,但函数式相关功能支持不多,比如典型的实用函数(map、reduce、select、exclude、forEach、find 等),这是 Go 故意为之,主要考虑简单性。随着 Go 引入泛型,相关实用函数会考虑纳入。

这方面,Java 也是后来才加入的。

注:Java5 开始支持泛型,Go 在 1.18 支持泛型。

9、基本类型包装器

Java 集合(数组除外)不能包含基本类型值(primitive values,比如 int、long 等),只能包含对象。因此,Java 为每个基本类型提供包装器类型。为了使集合更易于使用,Java 自动完成了这个包装过程(box),以将其插入到集合中,并在从集合中取出值时展开(unbox)该值。Go 没有这方面的限制。注意,需要使用装箱(box/unbox)是 Java 在内存使用方面不如 Go 高效的一方面原因。

10、Annotation(注解)

Go 没有注释。Go Struct 字段可以有标记(tag),这些标记提供类似但更有限的角色。

Annotation、function streams 和 lambda 使 Java(至少部分地)成为一种声明性语言。Go 几乎完全是一种命令式语言。这在有时候会使 Go 代码更加冗长。

此外,Go 中的 build constraints 在某些方面和 Annotation 有类似的效果。

11、可见性

Java 支持四种可见性:

  • private
  • default
  • protected
  • public

Go 没有以上关键字,Go 只有导出和非导出。导出类似 public,通过首字母大写来指定。首字母小写则是未导出。

12、重载/重写

在 Java 中,可以在同一范围内定义具有相同名称但具有不同签名(不同数量和/或类型的参数)的函数。这被称为(通过参数多态性的一种形式)重载函数。Go 不允许重载(overloaded)。

在Java中,具有相同名称和签名的函数可以在继承层次结构的较低层重新定义。这种重新定义的函数被称为(通过继承多态性)重写(overridden)。由于 Go 不支持继承,因此不允许这种方式的重写。不过 Go 中的嵌入类型,有类似重写的功能。

肯定还有其他 Java 有而 Go 没有的,欢迎交流!

参考

这个系列主要参考以下资料:

Go for Java Programmers

Java to Go in-depth tutorial

Go for Java Programmers: ebook

 

责任编辑:武晓燕 来源: polarisxu
相关推荐

2022-04-22 14:15:59

Go开发者受访者

2022-04-20 20:28:40

HDF 驱动框架鸿蒙操作系统

2022-05-03 22:25:57

Python浏览器语言

2022-05-07 10:09:01

开发Java日志

2022-05-10 16:04:40

编程语言PythonC语言

2022-04-01 15:18:04

HarmonyHDF 驱动鸿蒙

2022-03-31 07:52:01

Java多线程并发

2022-04-29 09:10:25

MobaXterm软件Linux

2022-04-15 08:00:00

FUSE开发Android

2022-04-07 14:33:31

操作系统鸿蒙HarmonyOS

2022-04-17 23:09:07

深度学习人工智能芯片

2022-04-08 08:26:03

JavaHTTP请求

2022-04-20 10:56:06

JavaJVM参数

2022-05-06 14:03:18

区块链NFT加密货币

2022-04-13 09:57:24

Go语言C语言程序开发

2022-04-08 09:01:56

脚本Go应用单元

2022-04-13 08:00:00

Hilla开发Java

2022-05-10 09:53:45

数据治理数据开发DataOps

2022-04-28 15:38:42

WebViewJavaUI

2022-04-07 11:16:45

GNOME发行版用户

同话题下的热门内容

Python 字符串总结,建议收藏!这份Java日志格式规范,拿走不谢!Mybatis-Plus官方发布分库分表神器,一个依赖轻松搞定!后端思维篇:如何应用设计模式优化代码改变 Python 对象规则的黑魔法 Metaclass几种限流算法的Go语言实现JMeter关联之正则表达式提取器在 Go 中实现一个支持并发的 TCP 服务端

编辑推荐

使用Kotlin做开发一个月后的感想面试官问你什么是消息队列?把这篇甩给他!五大自动化测试的Python框架图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)2018年最流行的十大编程语言,其中包括你用的语言吗?
我收藏的内容
点赞
收藏

51CTO技术栈公众号