Go与Java语法对比(一)

现在越来越多的公司后端开发语言从Java转向了Go,对于Java开发者来说,了解它们之间的语法差异是非常重要的。本文将深入对比Go语言和Java语言的语法特点,并通过示例代码来说明它们之间的区别。

启动入口

Java:在Java语言中,任意类中使用public static void 修饰的main(String[])方法,就是程序的启动入口

public class Main {

    public static void main(String[] args) {
        
    }
    
}

Go:在Go语言中,程序的启动入口也是main 函数,不过main函数必须放置在 main 包中

package main

func main() {
	
}

控制台打印Hello, world

Java:在Java语言中,控制台打印使用System.out#println方法,每行必须使用";"表示代码结束

public static void main(String[] args) {
    System.out.println("Hello, world!");
}

Go:在Go语言中,控制台打印需要导入fmt包,然后使用fmt#Println方法,每行最后一句代码可以省略";"

package main

import "fmt"

func main() {
	fmt.Println("Hello world!")
}

声明变量

Java:在Java语言中,变量定义格式为:[变量类型][变量名]

// JDK10以下, 必须指定变量类型
// 变量声明
String message;
// 变量赋值
message = "Hello world"; 
// 变量声明并赋值
String message = "Hello world"; 
// 声明多个变量
String message1 = "Hello", message2 = "world";
// final关键字声明, 不能再重新赋值其他值
final String message = "Hello world"; 

// JDK10及以上, 代码块中可以使用局部变量类型推断来声明变量
var message = "Hello world"; 

Go:在Go语言中,变量定义格式为:[var][变量名][变量类型]

// 变量声明
var message string 
// 变量赋值
message = "Hello world"
// 变量声明并赋值
var message string = "Hello, World!"
// 变量有初始值, Go可以推断类型
var message = "Hello, World!"
// Go还支持一种声明变量的简洁形式
message := "Hello, World!"
// 声明多个变量
var message1, message2 string = "Hello", "world"
// 推断类型
var message1, message2 = "Hello", "world"
// 简洁形式
message1, message2 := "Hello", "world"
// 常量声明, 不能再重新赋值其他值
const message = "Hello, World!"

函数定义

Java:在Java语言中,函数定义格式为:[访问修饰符][static][final][返回类型][方法名][方法参数]

// 普通方法
public int add(int a, int b) {
    return a + b;
}
// 私有方法
private int add(int a, int b) {
    return a + b;
}
// 不允许重写的方法
public final int add(int a, int b) {
    return a + b;
}
// 静态方法
public static int add(int a, int b) {
    return a + b;
}

Go:在Go语言中,函数定义格式为:[func][函数名][函数参数][返回类型]

// 不带返回值的函数
func print(s string) {
    fmt.Println(s)
}
// 带返回值的函数
func add(a int, b int) int {
    return a + b
}
// Go的访问权限定义有些特殊, 将函数名的首字母大写就表示该函数被导出, 其他包只能访问以大写字母开头的变量或者函
func Add(a int, b int) int {
    return a + b
}
// Go语言还支持多个返回值的函数
func calculate(a int, b int) (int, int)  {
	return a + b, a * b
}
// 连续多个类型一致的参数, 可以省略前面参数的类型
func calculate(a, b int) (int, int)  {
	return a + b, a * b
}
// 函数中返回值可以命名, 命名的返回值可以当做已声明的变量使用
func calculate(a, b int) (sum, product int)  {
	sum, product = a + b, a * b
    // 不需要明确指定返回值,默认返回 sum, product 的值
	return
}

Go语言中, 函数就相当于Java语言中的静态方法, 不需要创建对象就可以直接被使用。因为Go语言不是纯粹的面向对象编程语言, 没有类的概念。虽然Go本身不支持面向对象的语义,但使用Go语言中的结构体和接口,可以实现面向对象的编程风格。具体内容在后续介绍结构体和接口时再进行详细说明。

基本类型

Java和Go中都有的基本类型对比(Java中String是引用类型)

类型名称

Java

Go

布尔类型

boolean

bool

8 位有符号整型

byte

int8 / byte

16 位有符号整型

short

int16

32 位有符号整型

int

int32 / rune

64 位有符号整型

long

int64

32 位浮点数

float

float32

64 位浮点数

double

float64

字符串类型

String

string

Go语言还支持无符号整形和复数类型

  • 无符号整形:uint8, uint16, uint32, uint64

  • 复数类型:complex64, complex128

另外,有符号整形和无符号整形,Go语言中各有一种自适应类型int / uint:根据不同的底层平台,表示 32 或 64 位整型。

条件语句

Java:在Java语言中,条件语句的语法如下:

if (condition1) {
    // 执行条件为condition1时的代码块
} else if (condition2) {
    // 执行条件为condition2时的代码块
} else {
    // 执行剩余条件的代码块
}
// 当条件中代码只有一行时可以省略大括号
if (condition1) a = 1;
else if (condition2) a = 2;
else a = 3;

Go:在Go语言中,条件语句的语法基本与Java相同,不过条件中的圆括号 ( ) 可以省略,且 { } 是必要的,即使在 { } 之间只有一条语句

if condition1 {  
    // 执行条件为condition1时的代码块
} else if condition2 {
    // 执行条件为condition2时的代码块
} else {
    // 执行剩余条件的代码块
}
// Go语言中, 条件语句还可以含一个可选语句部分, 在条件判断之前运行
if num := 10; num % 2 == 0 { //checks if number is even
	fmt.Println(num,"is even") 
}  else {
	fmt.Println(num,"is odd")
}
// 需要注意的是, Go语言 else 语句必须在大括号 } 之后的同一行中, 如果不是不能通过编译
func main() {  
    num := 10
    if num % 2 == 0 {
        fmt.Println("the number is even") 
    }  
    // 此种方式编译器会报错, 原因是上一行的大括号 { 在编译时会在最后自动插入一个分号 ; 导致if语句被切成了两段代码, 从而无法通过编译
    else {
        fmt.Println("the number is odd")
    }
}

循环语句

Java:在Java语言中,循环语句的语法如下:

// while循环
while (condition) {
    // 循环体代码
}
// do-while循环
do {
    // 循环体代码
} while (condition);
// for循环, initialization是循环变量的初始化语句, condition是循环的退出条件, post是每次循环迭代后执行的语句
for (initialization; condition; post) {
    // 循环体代码
}
// for-each循环
int[] nums = {1,2,3,4};
for (int num : nums) {
    if (num == 1) {
        // continue 语句用来跳出循环中当前循环
        continue;
    }
    if (num == 4) {
        // break 语句用于终止循环
        break;
    }
    System.out.println(num);
}

Go:在Go语言中,并没有Java 语言中的 while 和 do while 循环,只有for循环

// 同Java中的for循环语法相同, 圆括号 ( ) 可以省略
for initialisation; condition; post {  
    // 循环体代码
}
// initialisation和post都是可选的, 分号也可以省略, 这个格式的 for 循环类似Java中对的 while 循环
for condition {  
    // 循环体代码
}
// condition可以省略, 此种格式对的 for 循环表示无限循环
for {
    // 循环体代码
}
// for-each循环, for-each会返回两个结果: 索引和该索引处的值
// 当我们只关心其中一个结果时, 可以使用 _ 空白符跳过不要的计算结果
nums := [4]int{1,2,3,4}
for _, num := range nums {
	if num == 1 {
		continue
	}
	if num == 4 {
		break
	}
	fmt.Println(num)
}

switch 语句

Java:在Java语言中,switch语句的语法如下:

switch (expression) {
case value1:
    // 当expression等于value1时执行的代码
    break;
case value2:
    // 当expression等于value2时执行的代码
    break;
default:
    // 当expression不等于任何case值时执行的代码
}

Go:在Go语言中,case代码块不需要以break语句结束,每执行完一个 case 后,会从 switch 语句中跳出来。如果想要继续执行后续case,可以使用 fallthrough 关键字

switch expression {
case value1:
    // 当expression等于value1时执行的代码
case value2:
    // 当expression等于value2时执行的代码
default:
    // 当expression不等于任何case值时执行的代码
}
// Go语言中表达式可以省略, 以下语句会执行前两个case中的代码块
num := 90
switch { 
case num < 50:
	fmt.Printf("%d is lesser than 50\n", num)
	fallthrough
case num < 100:
	fmt.Printf("%d is lesser than 100\n", num)
	fallthrough
case num < 200:
	fmt.Printf("%d is lesser than 200", num)
}
// 类似if语句, 条件部分也可以含一个可选语句
switch num := 1; num {
case 1:
	fmt.Println("One")
case 2:
	fmt.Println("Two")
default:
	fmt.Println("Unknown")
}

文章作者: Hakurei
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Zero
后端 Golang Java
喜欢就支持一下吧