---
title: 初試新的編譯程式語言 V (二) - 函式 & 變數
description: V - 用於開發可維護性軟體的簡單,快速,安全的編譯語言。
# image: https://hackmd.io/screenshot.png
tags: V,vlang
# robots: noindex, nofollow
langs: zh_Hant
---
# 初試新的編譯程式語言 V (二) - 函式 & 變數
V是一種靜態類型的編譯編程語言,用於構建可維護的軟件。它與Go類似,也受到Oberon,Rust,Swift的影響。
## Hello World
**hell_world.v**:
```v
// 這是單行註解
/*
這是多行註解
*/
/*
- `fn` 關鍵字 用來宣告函式(funciton)
- `fn main() {...}` 執行檔進入點
*/
fn main() {
println('hell world') // 內建函式。它將值打印到標準輸出。
}
```
要在V的程式碼中撰寫單行註解,以`//`開始;多行註解以`/*`開始並以`*/`結尾。
要宣告函式必須使用`fn`。返回型別在函式名稱後面宣告。在上方情況下,`main`不返回任何內容,因此省略了型別宣告。
要將值打印到標準輸出,可以調用`println`內建函式。
`fn main()`宣告可以在擔一個文件的程式中忽略。這在編寫小程序,“腳本(script)”或只是學習語言時很有用。
**hell_world.v**:
```v
println('hell world')
```
> 在終端執行`v run hell_world.v`,會編譯成並自動執行hell_world.exe
## 函式 (Fuctions)
**functions.v**:
```v
fn main() {
// 主函式 調用 下方的函式
println('add(77, 33)')
println(add(77, 33))
println('sub(100, 50)')
println(sub(100, 50))
println('mul(8, 8)')
println(mul(8, 8))
}
/*
- 函式參數名稱 在 函式名稱 後的`()`中宣告
- 函式參數型別 在 函式參數名稱 後宣告
- 函式返回型別 在 函式名稱 後的`()`之後宣告
*/
fn add(x int, y int) int {
return x + y
}
// 一樣的函式參數型別可以只宣告一次
fn sub(x, y int) int {
return x - y
}
fn mul(x, y int) int {
return x * y
}
```
型別的宣告需出現在參數的名稱之後。就像在Go和C中一樣,函式不能重載。
函式可以在宣告之前調用:`add`,`sub`和`mul`在`main`之後宣告,但仍然可以從`main`調用。
**functions.v**執行結果:
```
add(77, 33)
110
sub(100, 50)
50
mul(8, 8)
64
```
## 變數 (Variables)
**variables.v**:
```v
// 宣告並初始化一個字串(String)變數
name := 'Bob'
// 宣告並初始化一個整數(Integer)變數
age := 20
/*
型別轉換 `T(v)`
宣告並初始化一個64位元有號整數(64 bits signed integer)變數
*/
large_number := i64(9999999999)
println(name)
println(age)
println(large_number)
```
宣告一個變數的唯一方法是使用`:=`來初始化變數的值。
變數的型別是編譯器從右側的值推斷出來的。
要強制使用其他型別,請使用型別轉換:表達式`T(v)`將值`v`轉換為型別`T`.
V只允許在函式中定義變數。V沒有全域狀態(模組級別)的變數。
**variables.v**執行結果:
```
Bob
20
9999999999
```
在V中,**默認情況下變數是不可變的(immutable)**,意思指只使用`:=`將變數初始化後,變數的值將不能進行改變。
要更改變數,必須在變數名稱前使用`mut`宣告,並使用`=`來分配(assign)值給它
**mut_var.v**
```v
// 將mut刪除後嘗試編譯會出現錯誤
mut age := 20
println(age)
age = 21
println(age)
```
將mut刪除後嘗試編譯會出現錯誤:
```
mut_var.v : 4:5: `age` is immutable.
```
**注意:`:=`用於宣告和初始化,`=`用於分配。**
```v
fn main() {
// 代碼不會被編譯成功,因為未宣告變數age。
age = 21
}
```
編譯錯誤:
```
test.v:2:4: undefined: `age`
```
宣告一個變數但之後**未調用該變數**會導致編譯錯誤,如下:
```v
fn main() {
// 代碼不會被編譯成功,因為未調用變數age。
age := 21
}
```
編譯錯誤:
```
test.v:2:0: `age` declared and not used
```
在V中,**不允許使用變數遮蔽(variable shadowing)**。在子作用域宣告的變數若具有已在父作用域中使用的名稱,將導致編譯錯誤。
```
fn main() { // 父作用域
a := 10
if true { // 子作用域
a := 20 // 不允許使用變數遮蔽
}
}
```
編譯錯誤:
```
test.v:4:6: redefinition of `a`
```