方法与属性 #

一、方法定义 #

1.1 实例方法 #

mojo
struct Rectangle:
    var width: Float64
    var height: Float64
    
    fn __init__(inout self, width: Float64, height: Float64):
        self.width = width
        self.height = height
    
    fn area(self) -> Float64:
        return self.width * self.height
    
    fn perimeter(self) -> Float64:
        return 2.0 * (self.width + self.height)

def main():
    let rect = Rectangle(10.0, 5.0)
    print(f"Area: {rect.area()}")
    print(f"Perimeter: {rect.perimeter()}")

main()

1.2 可变方法 #

mojo
struct Counter:
    var value: Int
    
    fn __init__(inout self, value: Int = 0):
        self.value = value
    
    fn increment(inout self):
        self.value += 1
    
    fn decrement(inout self):
        self.value -= 1
    
    fn reset(inout self):
        self.value = 0

def main():
    var counter = Counter()
    counter.increment()
    counter.increment()
    print(counter.value)
    counter.reset()
    print(counter.value)

main()

1.3 静态方法 #

mojo
struct MathConstants:
    fn static pi() -> Float64:
        return 3.14159265359
    
    fn static e() -> Float64:
        return 2.71828182846
    
    fn static golden_ratio() -> Float64:
        return 1.61803398875

def main():
    print(f"Pi: {MathConstants.pi()}")
    print(f"e: {MathConstants.e()}")
    print(f"Golden Ratio: {MathConstants.golden_ratio()}")

main()

1.4 类方法 #

mojo
struct Person:
    var name: String
    var age: Int
    static var count: Int = 0
    
    fn __init__(inout self, name: String, age: Int):
        self.name = name
        self.age = age
        Person.count += 1
    
    fn static get_count() -> Int:
        return Person.count

def main():
    let p1 = Person("Alice", 25)
    let p2 = Person("Bob", 30)
    print(f"Total persons: {Person.get_count()}")

main()

二、属性 #

2.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 ** 2
    
    fn circumference(self) -> Float64:
        return 2.0 * 3.14159 * self.radius
    
    fn diameter(self) -> Float64:
        return 2.0 * self.radius

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

main()

2.2 属性验证 #

mojo
struct Temperature:
    var _celsius: Float64
    
    fn __init__(inout self, celsius: Float64):
        self._celsius = celsius
    
    fn celsius(self) -> Float64:
        return self._celsius
    
    fn fahrenheit(self) -> Float64:
        return self._celsius * 9.0 / 5.0 + 32.0
    
    fn set_celsius(inout self, value: Float64):
        if value >= -273.15:
            self._celsius = value

def main():
    var temp = Temperature(25.0)
    print(f"Celsius: {temp.celsius()}")
    print(f"Fahrenheit: {temp.fahrenheit()}")
    
    temp.set_celsius(30.0)
    print(f"New Celsius: {temp.celsius()}")

main()

2.3 只读属性 #

mojo
struct BankAccount:
    var _balance: Float64
    var _account_number: String
    
    fn __init__(inout self, account_number: String, initial: Float64):
        self._account_number = account_number
        self._balance = initial
    
    fn balance(self) -> Float64:
        return self._balance
    
    fn account_number(self) -> String:
        return self._account_number

def main():
    let account = BankAccount("123456", 1000.0)
    print(f"Account: {account.account_number()}")
    print(f"Balance: {account.balance()}")

main()

三、运算符重载 #

3.1 算术运算符 #

mojo
struct Vector2D:
    var x: Float64
    var y: Float64
    
    fn __init__(inout self, x: Float64, y: Float64):
        self.x = x
        self.y = y
    
    fn __add__(self, other: Vector2D) -> Vector2D:
        return Vector2D(self.x + other.x, self.y + other.y)
    
    fn __sub__(self, other: Vector2D) -> Vector2D:
        return Vector2D(self.x - other.x, self.y - other.y)
    
    fn __mul__(self, scalar: Float64) -> Vector2D:
        return Vector2D(self.x * scalar, self.y * scalar)

def main():
    let v1 = Vector2D(1.0, 2.0)
    let v2 = Vector2D(3.0, 4.0)
    
    let sum = v1 + v2
    let diff = v1 - v2
    let scaled = v1 * 2.0
    
    print(f"Sum: ({sum.x}, {sum.y})")
    print(f"Diff: ({diff.x}, {diff.y})")
    print(f"Scaled: ({scaled.x}, {scaled.y})")

main()

3.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 __eq__(self, other: Point) -> Bool:
        return self.x == other.x and self.y == other.y
    
    fn __ne__(self, other: Point) -> Bool:
        return not (self == other)

def main():
    let p1 = Point(1, 2)
    let p2 = Point(1, 2)
    let p3 = Point(3, 4)
    
    print(f"p1 == p2: {p1 == p2}")
    print(f"p1 == p3: {p1 == p3}")

main()

3.3 索引运算符 #

mojo
struct Matrix:
    var data: List[List[Int]]
    var rows: Int
    var cols: Int
    
    fn __init__(inout self, rows: Int, cols: Int):
        self.rows = rows
        self.cols = cols
        self.data = [[0 for _ in range(cols)] for _ in range(rows)]
    
    fn __getitem__(self, row: Int, col: Int) -> Int:
        return self.data[row][col]
    
    fn __setitem__(inout self, row: Int, col: Int, value: Int):
        self.data[row][col] = value

def main():
    var matrix = Matrix(3, 3)
    matrix[0, 0] = 1
    matrix[1, 1] = 2
    matrix[2, 2] = 3
    
    print(matrix[0, 0])
    print(matrix[1, 1])
    print(matrix[2, 2])

main()

3.4 字符串转换 #

mojo
struct Complex:
    var real: Float64
    var imag: Float64
    
    fn __init__(inout self, real: Float64, imag: Float64):
        self.real = real
        self.imag = imag
    
    fn __str__(self) -> String:
        if self.imag >= 0:
            return f"{self.real} + {self.imag}i"
        else:
            return f"{self.real} - {-self.imag}i"

def main():
    let c1 = Complex(3.0, 4.0)
    let c2 = Complex(5.0, -2.0)
    
    print(c1)
    print(c2)

main()

四、生命周期方法 #

4.1 初始化链 #

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

def main():
    let p1 = Person("Alice")
    let p2 = Person("Bob", 25)
    let p3 = Person("Charlie", 30, "charlie@example.com")
    
    print(p1.name, p1.age)
    print(p2.name, p2.age)
    print(p3.name, p3.email)

main()

4.2 复制方法 #

mojo
struct Buffer:
    var data: List[Int]
    
    fn __init__(inout self, size: Int):
        self.data = [0 for _ in range(size)]
    
    fn __copyinit__(inout self, other: Buffer):
        self.data = other.data

def main():
    let buf1 = Buffer(5)
    var buf2 = buf1
    
    print(len(buf2.data))

main()

4.3 移动方法 #

mojo
struct Resource:
    var name: String
    var handle: Int
    
    fn __init__(inout self, name: String):
        self.name = name
        self.handle = 1
    
    fn __moveinit__(inout self, owned other: Resource):
        self.name = other.name
        self.handle = other.handle
        other.handle = 0

def main():
    var res1 = Resource("MyResource")
    var res2 = res1
    
    print(res2.name)

main()

五、Trait实现 #

5.1 定义Trait #

mojo
trait Printable:
    fn __str__(self) -> String

trait Comparable:
    fn __lt__(self, other: Self) -> Bool
    fn __eq__(self, other: Self) -> Bool

5.2 实现Trait #

mojo
trait Printable:
    fn __str__(self) -> String

struct Point(Printable):
    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"({self.x}, {self.y})"

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

main()

六、方法最佳实践 #

6.1 单一职责 #

mojo
struct User:
    var name: String
    var email: String
    
    fn __init__(inout self, name: String, email: String):
        self.name = name
        self.email = email
    
    fn validate_email(self) -> Bool:
        return "@" in self.email
    
    fn display_name(self) -> String:
        return self.name.upper()

def main():
    let user = User("Alice", "alice@example.com")
    if user.validate_email():
        print(user.display_name())

main()

6.2 方法链 #

mojo
struct StringBuilder:
    var content: String
    
    fn __init__(inout self):
        self.content = ""
    
    fn append(inout self, text: String) -> StringBuilder:
        self.content += text
        return self
    
    fn append_line(inout self, text: String) -> StringBuilder:
        self.content += text + "\n"
        return self
    
    fn build(self) -> String:
        return self.content

def main():
    var sb = StringBuilder()
    let result = sb.append("Hello").append(", ").append("World").build()
    print(result)

main()

6.3 防御性编程 #

mojo
struct SafeDivision:
    fn static divide(a: Float64, b: Float64) -> Optional[Float64]:
        if b == 0:
            return None
        return a / b

def main():
    let result = SafeDivision.divide(10.0, 2.0)
    
    match result:
        case Some(value):
            print(value)
        case None:
            print("Division by zero")

main()

七、总结 #

本章学习了:

  • 实例方法与静态方法
  • 属性定义与访问
  • 运算符重载
  • 生命周期方法
  • Trait实现
  • 方法最佳实践

下一章,我们将学习所有权系统。

最后更新:2026-03-27