You are on page 1of 18

Programming Language Paradigms Term Report

Target programming language: GoLang

1. Programming Language Syntax


A. The naming rules for an identifier
1. 只能使用字母(a-z、A-Z)和數字(0-9)。
2. 命名可以包含底線(_),但不建議在命名的開頭或結尾使用底線,
並且不允許連續的底線(__)。
3. 區分大小寫,因此 myVariable 和 MyVariable 是不同的 identifier。
4. 命名應具有描述性且能清晰表達其用途,以提高程式碼的可讀性。
5. 避免使用縮寫、單一字母或過於簡短的命名,除非在特定的情況下有
明確的含義(比如只是單純的計數器)。
6. 避免使用保留關鍵字(如 if、else、for、func 等)作為 identifier。
7. 建議使用駝峰式命名法(camel case)或蛇形命名法(snake case)作
為命名慣例,以提高可讀性。例如,myVariable 或 my_variable。
B. Is there the dangling else problem in the language? How does it avoid or
handle the problem?
GoLang 沒有 dangling else problem,GoLang 解決 dangling else problem
的方式是使用大括號({})來明確指定每個 if 和 else 的作用範圍。在
GoLang 中,無論 if 語句的主體是單行還是多行,都必須使用大括號。

2. Names, Scopes, and Bindings


A. Define its static, stack-dynamic, and heap dynamic variables.
Go 在使用上並沒有提到 Stack 或 Heap,只會在 GC(garbage-collected)
內遵循一套嚴格的規則進行處理,變數在聲明時會根據其作用域和生
命周期的不同,被分配到不同的儲存位置。
以下用程式碼舉例,
Static:

“staticVar”是一個在 package 級別聲明的全局變數,它在整個程式執行


期間保持不變,可以在不同的函數中訪問和修改。
Stack-Dynamic Variables:

“x”是在 stackDynamicVar 函數中聲明的局部變數。每次調用函數時,


都會為變數 x 分配一個新的記憶體空間,並在函數執行完畢後釋放該
空間。
Heap-Dynamic Variables:
“x”是使用 new 函數動態分配的整數變數,存儲在 heap 上。它的生命
周期可以根據需要進行控制, GoLang 的垃圾回收機制(Garbage
Collection)會自動檢測並回收不再使用的 Heap-Dynamic Variables。
但是 new 如果使用在 slice, map 及 channel 身上的話,其初始的 Value
會是 nil,所以要使用 make 宣告:

B. Scoping rules
Local Variables:在 function 或 block 內宣告的變數稱為 Local
Variables。它們只能在該 function 或 block 內使用。Local Variables 不
為自身以外的函數所知。
Global Variables:在 function 外定義,通常在所有程式碼的最上方。
Global Variables 在 program 的整個生命週期內保持其值,任何函數都
可以訪問 Global Variables,也就是說,Global Variables 在宣告後可在
整個 program 中使用。
程式中,Global Variables 和 Local Variables 的名稱可以相同,但會以
Local Variables 優先。

Formal Parameters:參數在 function 中視為 Local Variables,並優先於


Global Variables。
3. Control Flow
A. Define operator precedence of the language.
如下表,具有最高優先級的運算符出現在表格的上方,具有最低優先
級的運算符出現在下方。在表達式中,將首先評估優先級較高的運算
符。
CATEGORY OPERATOR ASSOCIATIVITY
POSTFIX () [] -> . ++ - - Left to right
UNARY + - ! ~ ++ - - (type)* & Right to left
sizeof
MULTIPLICATIVE */% Left to right
ADDITIVE +- Left to right
SHIFT << >> Left to right
RELATIONAL < <= > >= Left to right
EQUALITY == != Left to right
BITWISE AND & Left to right
BITWISE XOR ^ Left to right
BITWISE OR | Left to right
LOGICAL AND && Left to right
LOGICAL OR || Left to right
ASSIGNMENT = += -= *= /= %=>>= Right to left
<<= &= ^= |=
COMMA , Left to right

B. Describe the control structures that are different from Java, such as how to
group multiple statements into a block, selection structure, and iteration
structure.
和 Java 一樣的是都用大括號({})區分不同的 block;GoLang 中不需要
分號結尾,預設一行就是一條資料,如果想將多個語句寫在同一行,
則必須使用分號;GoLang 會強制左大括號不換行,換行會報語法錯誤。
範例如下:
GoLang 中選擇結構有兩種形式:if 語句和 switch 語句。
在 GoLang 中,迭代結構有兩種形式:for 循環和 range 循環。for 的使

用方式與 Java 中的 for 類似,但是 GoLang 沒有 while 和 do-while。但


可以使用 for 來實現這些類型的迭代。range 用於遍歷
array、slice、channel 或 map 的元素,在 array 和 slice 中它返回元素的
索引和索引值,在 map 中返回 key-value 對。
4. Data Types
A. The scalar data types different from those in Java.
整數類型(Integer Types) int8
int16
int32
int64
uint8
uint16
uint32
uint64
int
rune I
byte
uintptr
浮點數類型(Floating-Point Types) float32
float64
複數類型(Complex Types) complex64
complex128
布爾類型(Boolean Type) bool
字符串類型(String Type) string
GoLang 中使用了固定大小的整數類型和明確的強制類型轉換,此外,
GoLang 中的字符型別不是 char,通常以 string 或 rune 來替代,rune 用
於表示 Unicode 字符,是一個整數型別(int32)。
B. The coercion rule and the method for explicit cast.
強制類型轉換規則:在 GoLang 中,只有兼容的資料類型之間才能進
行強制類型轉換。例如,整數類型之間可以相互轉換,浮點數類型之
間可以相互轉換,但整數類型不能直接轉換為浮點數類型。同樣,布
爾類型不能轉換為整數類型,反之亦然。
明確的類型轉換方法:在 GoLang 中,可以使用顯式類型轉換來將一
個資料類型轉換為另一個資料類型。語法是在要轉換的資料前面放置
目標資料類型的括號。例如,”var x int = int(3.14)”將浮點數轉換為整
數。
在進行類型轉換時,需要保證目標類型能夠容納源類型的值,否則會
發生截斷或溢出的情況。
C. Issues for array (or similar data type): Index types, When is the length of an
array determined? Etc.
1. 同一個陣列中只能存放同一個型態的值,比如整數陣列、浮點數陣
列、字串陣列
2. 陣列的長度在宣告後就固定不可以改變了
3. 宣告陣列的長度時只能是使用確定不變的數

不是宣告出來的 5 個值都一定要設定,golang 會自動分配預設值,


比如 string 會預設給空字串,int, uint, float32 等數值類的會給 0,
bool 會給 false。
第二種宣告 array 的方法:

另外要注意,如果有換行的話最後一行仍需以逗號做結尾(跟 json
不一樣 json 是最後一個不加,這個是最後一個一定要加)

用[…]可以讓 golang 幫我計算 array 的長度


5. Subroutines and Control Abstraction
A. Does it allow subroutine definitions to be nested? How?
Golang 中沒有巢狀的副程式,會出現” ./sum1.go:6:10: syntax error:
unexpected helper, expecting (”的報錯

但是 GoLang 中可以在一個副程式內部聲明和定義內部函數(Inner
Function)。內部函數可以訪問其外部函數的變數和參數,形成了一種
嵌套的效果。

B. Define the parameter passing mode of the language.


當你調用一個函數並傳遞參數時,Go 會將參數的值複製一份,然後將
該副本傳遞給函數。這樣,函數內部對參數的修改不會影響到原始參
數的值。
C. Can subroutines be passed as parameters, returned from functions? If so,
when are referencing environments bound (shallow or deep binding)?
GoLang 中,函數是 first-class,所以可以作為其它函數的參數進行傳遞,
然後在其它函數內調用執行,一般稱之為回調。下面是一個將函數作
為參數的簡單例子:

至於 referencing environments(引用環境),在 Go 中,當你將一個函


數作為參數傳遞或從函數中返回時,該函數會捕獲其所在的環境(即
該函數所使用的變量)的引用。這種捕獲的行為稱為 closure。
closure 在 Go 中使用的是深度綁定(deep binding)的方式。這意味著
當一個函數被捕獲為 closure 時,它所捕獲的環境中的變數和函數的值
都被保存下來,並且隨著 closure 的存在而存在,即使原始環境的作用
域已經結束。
D. Does it support generic functions? How?
Go 1.18 版本引入了泛型功能。在 Go 中编寫泛型函数,可以使用類型
參數(type parameter)。類型參數允许在函数或結構中使用通用類型,
以便在多種資料類型上進行操作。

6. Data Abstraction and Object Orientation


A. How are class (or abstract data type) instances created?
Go 使用結構體(struct)来創造自定義的資料類型,struct 是一種複合
型態,可以在一個 struct 內存放不同型態的變數。
p 是一個 person 型態 的變數,並不是「指標變數」,若想要能在函數
中更改 p 那麼我們需要取得 p 的指標才行。
B. How to define a constructor? When are constructors implicitly called?
Go 中沒有預設建構函式,但可以為任何型別定義函式,以下是使用
”init” 函式建立建構函式:

GoLang 中的 constructor 並不是在實例創建時自動調用的,而是需要顯


式的調用。
C. How does it support dynamic method binding?
在 GoLang 中,可以使用接口(interface)來實現動態方法绑定的效果。
通過定義接口,並讓 struct 實現該接口中的方法,我们可以在運行時
根據具體的對象類型來調用相應的方法。
7. Programming exercises (source code, development environment, and the
execution results)
執行畫面,執行 server.go 後,開啟 http://localhost:8080/

按 Open 按鈕
按 Send 按鈕

按 Close 按鈕

You might also like