在Java中,每一条语句以分号";"分隔,是否换行不影响代码的正确性。
在python中,取消了分号分隔方式,同时也取消了括号对于代码逻辑的作用(python中各种括号用于不同的数据类型)。因此采用了一种严格的缩进规则来控制代码规范。
而Golang取消了Java中的分号分隔,采用换行划分语句,但是保留了括号的使用。
但是Golang对花括号的使用较为严格。
在Java中,以下两种书写方式都是正确的
public String getString(Integer num) { return num.toString(); } public String getString(Integer num) { return num.toString(); }
在Golang中只允许一种格式:
func getString(num int) string { return strconv.Itoa(num) }
在Java中,变量可以声明之后,可以不被使用。
而Golang中声明的变量必须被使用,否则需要使用_来替代掉变量名,表明该变量不会被使用到:
func getString(num int) string { var temp = num // 没有使用者,无法编译 var _ = num // 正常编译 return strconv.Itoa(num) }
Java对方法、变量及类的可见域规则是通过private、protected、public关键字来控制的。
而Golang中控制可见域的方式只有一个,当字段首字母开头是大写时说明其是对外可见的、小写时只对包内成员可见。
package entity type Person struct { Name string Age int id string } type student struct { detail Person } func test() { // 本包内可见 person := &student{detail: Person{ Name: "Jrobin", Age: 24, id: "001", }} fmt.Println(person) }
package main import ( "fmt" entity "entity" ) func main() { // id字段不可见 person := &entity.Person{ Name: "Jrobin", Age: 24, } fmt.Println(person) }
public class Person { public String name; public int age; private String id; private class Student{ Person detail; } public void test(){ //本包内可见 Student student=new Student(); student.detail.name="Jrobin"; student.detail.age=24; student.detail.id="001"; System.out.println(toString()); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", id='" + id + '\'' + '}'; } }
public class Main { public static void main(String[] args) { //student类不可见 Person person=new Person(); person.name="Jrobin"; person.age=24; //id字段不可见 } }
此处Java代码设计仅为了尽可能与Golang代码进行对比,实际Golang的结构体与Java的类并不完全对应。
// Object:要声明的类型、v:变量名称、new Object()变量初始化 Object v = new Object(); int v1; String v2; int[] v3=new int[10]; int[] v4=new int[]{0,1,2}; Map<String,Integer> v5=new HashMap<>();//map,key为string类型,value为int类型 private int v6(int a){return 0;} int v7,v8;
// var:变量定义、v1:变量名称、int:变量类型 var v1 int var v2 string var v3 [10]int // 数组 var v4 []int // 数组切片 var v5 struct { f int } var v6 *int // 指针 var v7 map[string]int // map,key为string类型,value为int类型 var v8 func(a int) int var v9,v10 int //v9和v10都声明为int型
也可以采用:=自动推测变量类型:
var v1 int = 10 // 正确的使用方式1 var v2 = 10 // 正确的使用方式2,编译器可以自动推导出v2的类型 v3 := 10 // 正确的使用方式3,编译器可以自动推导出v3的类型
Golang的类型系统与Java相差不大,但是需要注意的是Java中的数组是属于引用类型,而Golang中的数组属于值类型,当向方法中传递数组时,Java可以直接通过该传入的数组修改原数组内部值(浅拷贝),但Golang则会完全复制出一份副本来进行修改(深拷贝):
public static void main(String[] args) { int[] array = {1, 2, 3}; change(array); System.out.println(Arrays.toString(array)); // -1,2,3 } private static void change(int[] array) { array[0] = -1; }
func main() { array := [...]int{1, 2, 3} change(array) fmt.Println(array) // 1,2,3 } func change(array [3]int) { array[0] = -1 }
在Golang中,只有切片、指针、channel、map及func属于引用类型,也就是在传递参数的时候,实质上复制的都是他们的指针,内部的修改会直接影响到外部:
func main() { slice := []int{1, 2, 3} changeSlice(slice) fmt.Println(slice) // -1,2,3 mapper := map[string]int { "num": 0, } changeMap(mapper) fmt.Println(mapper) // num = -1 array := [...]int{1, 2, 3} changePointer(&array) fmt.Println(array) // -1,2,3 intChan := make(chan int, 1) intChan <- 1 changeChannel(intChan) fmt.Println(<- intChan) // -1 } func changeChannel(intChan chan int) { <- intChan intChan <- -1 } func changePointer(array *[3]int) { array[0] = -1 } func changeMap(mapper map[string]int) { mapper["num"] = -1 } func changeSlice(array []int) { array[0] = -1 }