**註**:本文是根據官方網站翻譯得來,其中做了部分修改用於理解文章字義。 # mojo介紹 Mojo被設計為Python的超集,因此許多語言功能和你可能在Python中知道的概念可以直接翻譯成Mojo。例如一個 Mojo中的“Hello World”程式看起來和Python一模一樣: ``` pr ...
註:本文是根據官方網站翻譯得來,其中做了部分修改用於理解文章字義。
mojo介紹
Mojo被設計為Python的超集,因此許多語言功能和你可能在Python中知道的概念可以直接翻譯成Mojo。例如一個 Mojo中的“Hello World”程式看起來和Python一模一樣:
print("hello world")
hello world
您還可以導入現有的 Python 包並使用它們,就像您用Python編程,但我們稍後會談到這一點。
但是,重要的是要知道Mojo是一種全新的語言。 擁有,而不僅僅是帶有額外糖的 Python 的新實現。當你瞭解有關Mojo的更多信息,您會發現它與Mojo有更多共同點像 Rust 和 C++ 這樣的語言,除了它使用 Python 語法並完全支持導入的 Python 包。
所以讓我們開始吧!本筆記本介紹了 Mojo 語言的基礎知識,並且只需要一點編程經驗。
如果您想瞭解有關該語言的更多詳細信息,請查看Mojo編程手冊。
語言基礎
首先,Mojo是一種編譯語言,它的很多性能 記憶體安全功能就是從這一事實派生出來的。Mojo代碼可以是 提前編譯(AOT)或實時(JIT)。mojo也支持REPL 環境,例如運行 Jupyter 筆記本中的代碼的環境(命令行 REPL 即將推出)。
像其他編譯語言一樣,Mojo需要一個函數作為 程式的入口點。例如:main()
# 首先創建一個 .mojo 的文件 文檔上說文件名可以有表情可以試試
fn main():
var x: Int = 1
x +=1
print(x)
main()
2
如果你瞭解Python,你可能會期望“def main()”而不是“fn main())”。兩者實際上都在Mojo中工作,但使用“fn”的行為有點不同,我們將下麵討論。
當然,在REPL環境中不需要“main()”函數,因為如上面所示,當我們列印沒有“main()”函數的“helloworld”時。但是,當您想編寫自己的.mojo時,需要
main()函數
程式。
語法語義
Mojo使用了Python的所有語法和語義。(如果你不是 熟悉Python語法,網上有大量很棒的資源可以 教你。
例如,像Python一樣,Mojo使用換行符和縮進來定義代碼。 塊(不是大括弧),Mojo支持Python的所有控制流語法 例如條件和迴圈。if``for
但是,Mojo仍在進行中,因此Python中有一些東西。 尚未在 Mojo 中實現(請參閱 Mojo 路線圖)。所有缺失的Python功能會及時到來,但Mojo已經包含許多功能和 超出 Python 中原有的功能的功能。
因此,以下各節將重點介紹一些語言功能 是Mojo獨有的(與Python相比)。
Mojo函數可以用“fn”(如上所示)或“def”(如Python中)。“fn”聲明強制執行強類型和記憶體安全行為,而“def”提供Python風格的動態行為。
“fn”和“def”函數都有其值兩者兼而有之。然而,為了本介紹的目的,我們將僅關註“fn”函數。有關兩者的更多詳細信息,請參閱編程手冊。
在以下部分中,您將瞭解“fn”函數是如何強制執行的代碼中的強類型和記憶體安全行為。
您可以使用聲明變數,例如上面的“main()”函數中的“x”`var’創建可變值,或者使用let’創建不可變值。
var: 聲明全局變數(表示可以在全局獲取到),在mojo 中用var 聲明的變數是可變的
let:聲明臨時變數(例:在函數或迴圈中聲明,那麼只能在函數中獲取,在函數外或者其他函數中是獲取不到該值的),let聲明的變數是不可變的
繼續,在上面的“main()”函數中將“var”更改為“let”,然後運行它。您將得到如下編譯器錯誤:
fn main():
let x: Int = 1
x +=1
print(x)
main()
```
error: Expression [15]:7:5: expression must be mutable for in-place operator destination
x += 1
^
```
# 錯誤:表達式[15]:7:5:對於就地運算符目標,表達式必須是可變的
這是因為“let”使其不可變,所以不能增加值。如果你刪除“var”,你會得到一個錯誤,因為“fn`函數需要顯式的變數聲明(與“def”函數不同)。
fn main():
x = 1
main()
"""
error: Expression [1]:6:5: use of unknown declaration 'x', 'fn' declarations require explicit variable declarations
x = 1
^
expression failed to parse (no further compiler diagnostics)
"""
錯誤:表達式[1]:6:5:使用未知聲明“x”、“fn”聲明需要顯式變數聲明
x=1
^
表達式解析失敗(沒有進一步的編譯器診斷)
最後,請註意,“x”變數有一個顯式的“Int”類型規範。“fn”中的變數不需要聲明類型,但是需要聲明var let
,有時如果省略聲明類型,Mojo將推斷類型,如下所示:
fn do_math():
let x: Int = 1
let y = 2
print(x + y)
do_math()
3
函數參數和返回
與局部變數不同,函數中的參數必須指定類型。fn
若要從函數返回值,必須使用簽名末尾的箭頭。fn``->
例如:
fn add(x: Int, y: Int) -> Int:
return x + y
z = add(1, 2)
print(z)
3
參數可變性和所有權
自變數的可變性和所有權
現在,讓我們探討如何在函數中共用參數值。
請註意,如上所述,“add()”不會修改“x”或“y”,它只讀取價值觀事實上,正如所寫的,函數不能修改它們,因為fn
預設情況下,參數是不可變的引用。
就論點慣例而言,這被稱為“借用”,儘管作為“fn”函數的預設值,可以使用borrowed
聲明如下(其行為與上面的“add()”完全相同):
fn add(borrowed x: Int, borrowed y: Int) -> Int:
return x + y
如果希望參數是可變的,則需要聲明該參數inout
。這意味著對參數in側所做的更改函數在函數外可見。
例如,此函數可以修改原始變數:
fn add_inout(inout x: Int, inout y: Int) -> Int:
x += 1
y += 1
return x + y
var a = 1
var b = 2
c = add_inout(a, b)
print(a)
print(b)
print(c)
2
3
5
另一種選擇是將參數聲明為“owned”,這提供了函數對值的完全所有權(使他成為可變的,並保證是唯一的)。這樣,函數可以修改值,而不用擔心影響函數外的變數。例如:
fn set_fire(owned text: String) -> String:
text += "