结构体基础 #

一、结构体定义 #

1.1 基本语法 #

mojo
struct Point:
    var x: Int
    var y: Int
    
    fn __init__(inout self, x: Int, y: Int):
        self.x = x
        self.y = y

def main():
    let p = Point(10, 20)
    print(f"Point({p.x}, {p.y})")

main()

1.2 字段定义 #

mojo
struct Person:
    var name: String
    var age: Int
    var email: String
    
    fn __init__(inout self, name: String, age: Int, email: String):
        self.name = name
        self.age = age
        self.email = email

def main():
    let person = Person("Alice", 25, "alice@example.com")
    print(person.name)
    print(person.age)

main()

1.3 默认值 #

mojo
struct Config:
    var host: String
    var port: Int
    var timeout: Int
    
    fn __init__(inout self, host: String = "localhost", port: Int = 8080, timeout: Int = 30):
        self.host = host
        self.port = port
        self.timeout = timeout

def main():
    let cfg1 = Config()
    let cfg2 = Config("example.com", 443)
    
    print(f"{cfg1.host}:{cfg1.port}")
    print(f"{cfg2.host}:{cfg2.port}")

main()

二、实例化 #

2.1 基本实例化 #

mojo
struct Rectangle:
    var width: Int
    var height: Int
    
    fn __init__(inout self, width: Int, height: Int):
        self.width = width
        self.height = height

def main():
    let rect = Rectangle(100, 50)
    print(rect.width)

main()

2.2 命名参数实例化 #

mojo
struct User:
    var name: String
    var age: Int
    var active: Bool
    
    fn __init__(inout self, name: String, age: Int, active: Bool = True):
        self.name = name
        self.age = age
        self.active = active

def main():
    let user = User(name="Bob", age=30)
    print(user.name)

main()

2.3 可变实例 #

mojo
struct Counter:
    var count: Int
    
    fn __init__(inout self, count: Int = 0):
        self.count = count

def main():
    var counter = Counter()
    counter.count += 1
    print(counter.count)

main()

三、字段访问 #

3.1 读取字段 #

mojo
struct Book:
    var title: String
    var author: String
    var pages: Int
    
    fn __init__(inout self, title: String, author: String, pages: Int):
        self.title = title
        self.author = author
        self.pages = pages

def main():
    let book = Book("Mojo Guide", "Modular", 300)
    
    print(book.title)
    print(book.author)
    print(book.pages)

main()

3.2 修改字段 #

mojo
struct BankAccount:
    var balance: Float64
    
    fn __init__(inout self, balance: Float64):
        self.balance = balance

def main():
    var account = BankAccount(1000.0)
    
    account.balance += 500.0
    print(account.balance)
    
    account.balance -= 200.0
    print(account.balance)

main()

3.3 只读结构体 #

mojo
struct ReadOnlyPoint:
    let x: Int
    let y: Int
    
    fn __init__(inout self, x: Int, y: Int):
        self.x = x
        self.y = y

def main():
    let p = ReadOnlyPoint(10, 20)
    print(p.x)

main()

四、嵌套结构体 #

4.1 结构体作为字段 #

mojo
struct Address:
    var street: String
    var city: String
    var zip: String
    
    fn __init__(inout self, street: String, city: String, zip: String):
        self.street = street
        self.city = city
        self.zip = zip

struct Employee:
    var name: String
    var address: Address
    
    fn __init__(inout self, name: String, address: Address):
        self.name = name
        self.address = address

def main():
    let addr = Address("123 Main St", "Beijing", "100000")
    let emp = Employee("Alice", addr)
    
    print(emp.name)
    print(emp.address.city)

main()

4.2 嵌套初始化 #

mojo
struct Point:
    var x: Int
    var y: Int
    
    fn __init__(inout self, x: Int, y: Int):
        self.x = x
        self.y = y

struct Line:
    var start: Point
    var end: Point
    
    fn __init__(inout self, start: Point, end: Point):
        self.start = start
        self.end = end

def main():
    let line = Line(Point(0, 0), Point(10, 10))
    print(f"({line.start.x}, {line.start.y}) -> ({line.end.x}, {line.end.y})")

main()

五、结构体方法 #

5.1 实例方法 #

mojo
struct Circle:
    var radius: Float64
    
    fn __init__(inout self, radius: Float64):
        self.radius = radius
    
    fn area(self) -> Float64:
        return 3.14159 * self.radius * self.radius
    
    fn circumference(self) -> Float64:
        return 2.0 * 3.14159 * self.radius

def main():
    let circle = Circle(5.0)
    print(f"Area: {circle.area()}")
    print(f"Circumference: {circle.circumference()}")

main()

5.2 修改实例方法 #

mojo
struct MutablePoint:
    var x: Int
    var y: Int
    
    fn __init__(inout self, x: Int, y: Int):
        self.x = x
        self.y = y
    
    fn move(inout self, dx: Int, dy: Int):
        self.x += dx
        self.y += dy

def main():
    var point = MutablePoint(0, 0)
    point.move(10, 20)
    print(f"({point.x}, {point.y})")

main()

5.3 静态方法 #

mojo
struct MathUtils:
    fn static add(a: Int, b: Int) -> Int:
        return a + b
    
    fn static multiply(a: Int, b: Int) -> Int:
        return a * b

def main():
    print(MathUtils.add(5, 3))
    print(MathUtils.multiply(5, 3))

main()

六、特殊方法 #

6.1 构造函数 #

mojo
struct Vector:
    var x: Float64
    var y: Float64
    var z: Float64
    
    fn __init__(inout self, x: Float64, y: Float64, z: Float64):
        self.x = x
        self.y = y
        self.z = z
    
    fn __init__(inout self, value: Float64):
        self.x = value
        self.y = value
        self.z = value

def main():
    let v1 = Vector(1.0, 2.0, 3.0)
    let v2 = Vector(0.0)
    
    print(f"v1: ({v1.x}, {v1.y}, {v1.z})")
    print(f"v2: ({v2.x}, {v2.y}, {v2.z})")

main()

6.2 析构函数 #

mojo
struct Resource:
    var name: String
    
    fn __init__(inout self, name: String):
        self.name = name
        print(f"Resource {self.name} created")
    
    fn __del__(owned self):
        print(f"Resource {self.name} destroyed")

def main():
    let res = Resource("MyResource")
    print("Using resource")

main()

6.3 字符串表示 #

mojo
struct Point:
    var x: Int
    var y: Int
    
    fn __init__(inout self, x: Int, y: Int):
        self.x = x
        self.y = y
    
    fn __str__(self) -> String:
        return f"Point({self.x}, {self.y})"

def main():
    let p = Point(10, 20)
    print(p)

main()

七、结构体与函数 #

7.1 作为参数 #

mojo
struct Point:
    var x: Int
    var y: Int
    
    fn __init__(inout self, x: Int, y: Int):
        self.x = x
        self.y = y

fn distance(p1: Point, p2: Point) -> Float64:
    let dx = p2.x - p1.x
    let dy = p2.y - p1.y
    return (dx * dx + dy * dy) ** 0.5

def main():
    let p1 = Point(0, 0)
    let p2 = Point(3, 4)
    print(distance(p1, p2))

main()

7.2 作为返回值 #

mojo
struct Point:
    var x: Int
    var y: Int
    
    fn __init__(inout self, x: Int, y: Int):
        self.x = x
        self.y = y

fn midpoint(p1: Point, p2: Point) -> Point:
    return Point((p1.x + p2.x) // 2, (p1.y + p2.y) // 2)

def main():
    let p1 = Point(0, 0)
    let p2 = Point(10, 20)
    let mid = midpoint(p1, p2)
    print(f"Midpoint: ({mid.x}, {mid.y})")

main()

八、结构体最佳实践 #

8.1 封装 #

mojo
struct BankAccount:
    var _balance: Float64
    
    fn __init__(inout self, initial: Float64):
        self._balance = initial
    
    fn balance(self) -> Float64:
        return self._balance
    
    fn deposit(inout self, amount: Float64):
        if amount > 0:
            self._balance += amount
    
    fn withdraw(inout self, amount: Float64) -> Bool:
        if amount > 0 and amount <= self._balance:
            self._balance -= amount
            return True
        return False

def main():
    var account = BankAccount(1000.0)
    account.deposit(500.0)
    account.withdraw(200.0)
    print(account.balance())

main()

8.2 不可变设计 #

mojo
struct ImmutablePoint:
    let x: Int
    let y: Int
    
    fn __init__(inout self, x: Int, y: Int):
        self.x = x
        self.y = y
    
    fn moved(self, dx: Int, dy: Int) -> ImmutablePoint:
        return ImmutablePoint(self.x + dx, self.y + dy)

def main():
    let p1 = ImmutablePoint(10, 20)
    let p2 = p1.moved(5, 5)
    print(f"p1: ({p1.x}, {p1.y})")
    print(f"p2: ({p2.x}, {p2.y})")

main()

九、总结 #

本章学习了:

  • 结构体定义与实例化
  • 字段定义与访问
  • 嵌套结构体
  • 实例方法
  • 特殊方法
  • 结构体与函数
  • 最佳实践

下一章,我们将学习方法与属性的高级特性。

最后更新:2026-03-27