⚡ 高效能 × Python 風格 × AI 基礎設施

Mojo 編程語言詳細教學

Mojo 是一種由 Modular 推動的程式語言,採用接近 Python 的語法風格,同時強調靜態型別、記憶體安全、所有權模型與高效能執行,非常適合用於高效能運算、系統程式設計與 AI 基礎設施開發。

本網站內容以官方文件為基礎整理為繁體中文教學版,適合已懂 Python、想快速理解 Mojo 核心概念的學習者。
Python 風格語法 靜態型別 Struct Ownership Python Interop Compile-time Parameters
必學 6 大主題 變數、函式、流程控制、Struct、所有權、Python 互通
3 種核心流程控制 ifwhilefor
2 種 Python 互通方向 Mojo 呼叫 Python、Python 呼叫 Mojo
互動學習 內建測驗、自動計分、學習摘要

一、認識 Mojo

如果你熟悉 Python,你會發現 Mojo 的許多語法看起來很親切;但它不是單純的 Python 替代品,而是加入靜態型別、值語意、所有權控制與編譯最佳化能力的獨立語言。

Mojo 的定位

Mojo 官方文件指出,Mojo 是一個特別為高效能 AI 基礎設施與異質硬體設計的語言。它吸收 Python 的可讀性,同時加入更強的型別系統與底層控制能力。

像 Python 的地方

  • def 定義函式
  • 使用縮排表示程式區塊
  • 語法可讀性高

不像 Python 的地方

  • 靜態型別更明確
  • 有所有權與參數傳遞慣例
  • 支援編譯期參數化

二、語法教學

以下依照學習順序,從最基本的程式結構一路講到 Mojo 較具特色的功能。
基礎 01:main 與第一支程式

每個可執行的 Mojo 程式都需要有一個無參數的 main() 作為入口點。這一點和許多編譯型語言類似。

Hello World
def main():
    print("Hello, world!")
重點:def 用來宣告函式,冒號後搭配縮排區塊。Mojo 與 Python 一樣,以縮排表示程式結構。
基礎 02:變數與靜態型別

Mojo 可以像 Python 一樣直接指定值,也可以使用 var 進行明確宣告。即使省略型別,編譯器也會在第一次賦值時推導出固定型別。

隱式宣告

def main():
    x = 10
    y = x * x
    print(y)

顯式宣告

def main():
    var x: Int = 10
    var sum: Int
    sum = x + x
    print(sum)
注意:Mojo 是靜態型別。若一開始 x = 10,之後再寫 x = "Foo" 會產生型別錯誤。
基礎 03:函式

Mojo 使用 def 定義函式。函式參數必須宣告型別;如果函式會回傳值,通常以 -> 型別 標示回傳型別。

基本函式

def greet(name: String) -> String:
    return "Hello, " + name + "!"

帶預設值的參數

def my_pow(base: Int, exp: Int = 2) -> Int:
    return base ** exp

Mojo 的函式預設是「不拋出錯誤」的;如果某函式可能把錯誤往外傳播,就要在函式宣告中加入 raises

def main() raises:
    var name: String = input("請輸入名字:")
    print("你好," + name)
初學者可先記住:參數要有型別、可回傳值要標回傳型別、會傳遞錯誤時要加 raises
基礎 04:流程控制

初學 Mojo 最先要學會的流程控制有三個:ifwhilefor

if / elif / else

def check_temp(temp_celsius: Int):
    if temp_celsius > 20:
        print("天氣偏暖")
    elif temp_celsius < 20:
        print("天氣偏涼")
    else:
        print("剛剛好")

while

def count_up():
    var x: Int = 0
    while x < 5:
        print(x)
        x += 1

for + range()

def loop_demo():
    for i in range(5):
        print(i)
range() 在 Mojo 中是可迭代序列,官方文件特別提到它以產生器形式逐步生成值,而不是一次建立整批資料。
基礎 05:Struct 自訂型別

struct 是 Mojo 定義自訂型別的主要方式。它像 Python 的 class,但最大差異是: Mojo struct 是在編譯期就固定好的靜態結構,不能像 Python 類別一樣在執行期任意動態修改。

手動建構子

struct MyPair:
    var first: Int
    var second: Int

    def __init__(out self, first: Int, second: Int):
        self.first = first
        self.second = second

使用 @fieldwise_init

@fieldwise_init
struct MyPair(Copyable):
    var first: Int
    var second: Int

    def dump(self):
        print(self.first, self.second)

@fieldwise_init 會自動幫你建立對應欄位的初始化邏輯,能少寫很多樣板程式碼。

基礎 06:所有權與參數傳遞慣例

Mojo 很重要的一個特色是所有權模型。官方文件整理的核心概念是:一個值在同一時間只有一個擁有者;當擁有者生命週期結束,值就會被銷毀;若仍有引用存在,生命週期會被延長。

常見參數慣例

  • read:不可變參考(預設)
  • mut:可變參考,可直接修改原值
  • var:函式取得值的所有權
  • out:常用於建構子中的 self

記憶技巧

  • 沒寫時,多半當成 read
  • 想改原本資料,用 mut
  • 想接手管理該值,用 var
使用 mutable reference
def add(mut x: Int, read y: Int):
    x += y

def main():
    var a = 1
    var b = 2
    add(a, b)
    print(a)  # 3
取得所有權
def take_text(var text: String):
    text += "!"
    print(text)

def main():
    var message = "Hello"
    take_text(message)
進階情況中,var 常會搭配轉移語意一起理解;對初學者而言,先掌握「函式可能接手擁有權」即可。
基礎 07:編譯期參數化

Mojo 支援用方括號宣告「編譯期參數」,這和一般函式括號裡的執行期參數不同。官方文件稱這種設計為 parameterization,可讓程式在編譯期做更多最佳化或生成特化版本。

def repeat[count: Int](msg: String):
    comptime for i in range(count):
        print(msg)

def main():
    repeat[3]("Hello")
重點:[count: Int] 是編譯期參數,(msg: String) 才是執行期參數。
基礎 08:Python 互通

Mojo 官方說明了兩個方向的 Python 互通能力:

  • Mojo 呼叫 Python:在 Mojo 中匯入既有 Python 模組並直接使用。
  • Python 呼叫 Mojo:把 Mojo 的高效能功能提供給 Python 程式呼叫。
Mojo 呼叫 Python(NumPy 範例)
from std.python import Python

def main() raises:
    var np = Python.import_module("numpy")
    var ar = np.arange(15).reshape(3, 5)
    print(ar)
    print(ar.shape)
如果你本來就有大量 Python 生態系工具,Mojo 的這項能力非常重要,因為它讓你不必一次重寫整個專案。

三、範例應用

以下提供幾個由淺入深的 Mojo 練習範例,幫助你把語法知識轉成實作能力。

範例 1:打招呼程式

練習輸入、字串串接、raises

def main() raises:
    var name: String = input("請輸入你的名字:")
    var greeting: String = "你好," + name + "!"
    print(greeting)

範例 2:平方與次方函式

練習函式定義、回傳型別、預設參數。

def square(x: Int) -> Int:
    return x * x

def power(base: Int, exp: Int = 2) -> Int:
    return base ** exp

def main():
    print(square(7))
    print(power(3))
    print(power(2, 5))

範例 3:清單與迴圈

練習 Listforrange()

def main():
    nums = [12, -7, 64]
    nums.append(100)

    for i in range(len(nums)):
        print("索引", i, "值 =", nums[i])

範例 4:Struct 建模

練習自訂型別與方法。

@fieldwise_init
struct Student(Copyable):
    var name: String
    var score: Int

    def passed(self) -> Bool:
        return self.score >= 60

def main():
    var s = Student("小明", 85)
    print(s.name)
    print(s.passed())

範例 5:可變參考

練習 mut 修改原始資料。

def add_bonus(mut score: Int, bonus: Int):
    score += bonus

def main():
    var exam = 70
    add_bonus(exam, 15)
    print(exam)  # 85

範例 6:呼叫 Python NumPy

練習 Python 生態整合。

from std.python import Python

def main() raises:
    var np = Python.import_module("numpy")
    var arr = np.array([1, 2, 3, 4, 5])
    print(arr.mean())

練習建議路線

  1. 先完成 Hello World、輸入輸出、函式。
  2. 接著練習 ifwhilefor
  3. 再學 Liststruct,開始寫小型資料模型。
  4. 理解 readmutvar 差異。
  5. 最後再學編譯期參數化與 Python 互通。

四、小測驗

做完以下題目後,按下「計算分數」,系統會自動顯示你的得分與簡要評語。

1. Mojo 可執行程式的入口點函式通常是哪一個?

2. 如果函式可能把錯誤往外傳播,應該在宣告中加入哪個關鍵字?

3. 在 Mojo 中,未特別標示時,函式參數預設通常視為哪一種傳遞慣例?

4. 哪一項最能描述 Mojo 的 struct?

5. 下列哪一個是編譯期參數化函式的正確概念?

6. Python 互通中,哪一個範例最符合 Mojo 官方展示的作法?

五、資料來源與延伸閱讀

以下連結皆來自 Mojo / Modular 官方文件,建議搭配本教學網站一起閱讀。
  1. Mojo Manual 總覽: https://docs.modular.com/mojo/manual/
  2. Mojo language basics: https://docs.modular.com/mojo/manual/basics/
  3. Get started with Mojo: https://docs.modular.com/mojo/manual/get-started/
  4. Functions: https://docs.modular.com/mojo/manual/functions/
  5. Control flow: https://docs.modular.com/mojo/manual/control-flow/
  6. Structs: https://docs.modular.com/mojo/manual/structs/
  7. Ownership: https://docs.modular.com/mojo/manual/values/ownership/
  8. Python interoperability: https://docs.modular.com/mojo/manual/python/
版本提醒:Mojo 還在持續演進中,部分語法與最佳實務可能隨官方版本更新而調整,建議實作時仍以官方文件為準。