从Java角度看Golang
前言
熟練掌握一門編程語言,再學一門新的會很容易上手,因為語言都是相通的,設計模式類似,只不過用處不大一樣。所以一般學一門語言時,我都會用自己比較熟悉的語言做一個類比,輔助自己理解。
現在大多數同學學的都是Java,而Golang是一門比較熱門的語言,廣泛用于云原生生生態。那么這篇文章,我用Java的視角看Golang,給出一些Java和Golang的語法類比
Java和Golang的語法類比
1. 基礎數據類型
Java基礎數據類型有8種,int、long、short、float、double、byte、boolean、char
Golang基礎數據類型有7種,整型(6種)byte、int、int8、int16、int32、int64、無符號整型(6種):uint、uint8、uint16、uint32、uint64、uintptr,浮點型(2種)float32、float64,復數類型(2種):complex64,complex128、字符:rune、字符串:string
并且Golang還有一些符合數據類型,如指針、數組,切片(類似Python),結構體(可以和C++的結構體類比,但是我把他理解成Java的類),還有并發編程的channel等
2. 賦值對比
Java:int a = 3;
Golang中:
全局變量:int a = 3,
局部變量:int a := 3,注意局部變量只能用:=聲明
3.函數定義
使用Java的朋友應該很少使用“函數”這個詞,因為對于Java來說,所有的“函數”都是基于“類”這個概念構建的,也就是只有在“類”中才會包含所謂的“函數”,這里的“函數”被稱為“方法”。
而“函數”這個詞源于面向過程的語言,所以在Golang中,“函數”和“方法”的最基本區別是:
函數不基于結構體而是基于包名調用,方法基于結構體調用。下面是一個例子,可以直觀地看出方法和函數的區別:
package?entity
import?"fmt"
type?Person?struct?{
Name?string
Age?int
id?string
}
// Person結構體/指針可調用的"方法",屬于Person結構體
func?(p *Person)?Solve()?{
fmt.Println(p)
}
// 任何地方都可調用的"函數",不屬于任何結構體,可通過entity.Solve調用
func?Solve(p *Person)?{
fmt.Println(p)
}
func?main()?{
personPoint :=?new(entity.Person)?// 通過new方法創建結構體指針
entity.Solve(personPoint)?// 函數調用
personPoint.Solve()?// 方法調用
}
4.權限描述符
Java的權限描述符有private,public,protected,default
Golang中則是,如變量,結構體,方法等首字母大寫,則其他包都可以訪問,首字母小寫,則不可訪問
5.Java和Golang數組定義
Java:
ArrayType[] ArrayName =?new?ArrayType[length];
Golang:
var?ArrayName[length] ArrayType = [length]ArrayType(.....)
6.指針與引用
Java中底層對指針進行了封裝,我們不需要像C++一樣關注指針(但是Java中引用的概念感覺和指針差不多,理解好引用的話理解指針也完全沒有問題)
Golang中存在顯式的指針操作,但是Golang的指針不像C那么復雜,不能進行指針運算。
7.Java中的new和Golang中的new make
Java中我們要new一個類,此時在堆內存中創建了這個對象
Golang中
(1) new和make都不是go的關鍵字,而是go預定義的函數。這意味著我們可以將new或者make重新定義為其他類型。比如:
func?delta(new,?make?int) int {?return?make?-?new?}
var p * int
p = new(int)
類似C++的用法。意思是,創建一個int類型變量,為int類型的新值分配并且清零一塊內存空間,將內存空間的地址作為結果返回,這個結果就是指向int類型的值的指針.
(2) make返回一個變量而new返回一個變量的指針
8.Java和Golang的標準輸出流
Java中是System.out.println
Golang中則是利用fmt包,可以與Java,C++進行類比
package?main
import?(
"fmt"
)
func?main()?{
var?str?string
fmt.Scanln(&str)
fmt.Printf("INPUT :%s\n", str);
fmt.Println("Hello world");
}
9.Java與Golang的,面向對象編程
面向對象的四大特性:封裝,繼承,抽象,多態
Java編程中我們一般要先定義接口,并且把接口實現,過程比較約定俗成,代碼量也比較大
Golang中給我的感覺則是更加自由,寫起來更像面向過程(僅是更像),代碼量比Java要少很多。我們可以用struct封裝一些屬性,類比Java中的類。而Golang中的接口不是需要像Java中先定義再實現,一般項目中是通過模塊分層,實現一個接口層
10.Java與Golang的多線程
Java中線程可以繼承Thread,實現Runnalbe接口,或者實現Callable接口,或者從線程池創建。Java 語言里解決并發問題靠的是多線程,但線程是個重量級的對象,不能頻繁創建、銷毀,而且線程切換的成本也很高,為了解決這些問題,Java SDK 提供了線程池。然而用好線程池并不容易,Java 圍繞線程池提供了很多工具類,這些工具類學起來也不容易。那有沒有更好的解決方案呢?Java 語言里目前還沒有,但是其他語言里有,這個方案就是協程(Coroutine)。
我們可以把協程簡單地理解為一種輕量級的線程。從操作系統的角度來看,線程是在內核態中調度的,而協程是在用戶態調度的,所以相對于線程來說,協程切換的成本更低。協程雖然也有自己的棧,但是相比線程棧要小得多,典型的線程棧大小差不多有 1M,而協程棧的大小往往只有幾 K 或者幾十 K。所以,無論是從時間維度還是空間維度來看,協程都比線程輕量得多。
Golang中使用的就是協程了,在 Golang 中創建協程非常簡單,在下面的示例代碼中,要讓 hello() 方法在一個新的協程中執行,只需要go hello("World")?這一行代碼就搞定了。你可以對比著想想在 Java 里是如何“辛勤”地創建線程和線程池的吧,我的感覺一直都是:每次寫完 Golang 的代碼,就再也不想寫 Java 代碼了。
import?(
"fmt"
"time"
)
func?hello(msg?string) {
fmt.Println("Hello "?+ msg)
}
func?main()?{
// 在新的協程中執行 hello 方法
go?hello("World")
fmt.Println("Run in main")
// 等待 100 毫秒讓協程執行結束
time.Sleep(100?* time.Millisecond)
}
總結
總結以上就是學習和使用過程中的一些簡單對比,可能還有不正確,不深入的地方,隨著學習的深入也會不斷更新
Golang現在也是一門很有發展的語言,大家感興趣可以學習一波~
總結
以上是生活随笔為你收集整理的从Java角度看Golang的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Cloud Gateway
- 下一篇: java美元兑换,(Java实现) 美元