Pular para o conteúdo

Funções Associadas e Múltiplos impl

Nesta página

Funções associadas são definidas no impl mas não recebem self — não precisam de uma instância para serem chamadas. O idioma padrão é usar new (ou qualquer nome descritivo) como construtor. A chamada usa :: em vez de .:

Point::new(x, y) e Point::origin() são funções associadas; distance é método de instância.

03-associated-functions.zolo
Playground
// Feature: Associated functions (no `self`) — constructors and helpers

// Syntax: define `fn name(...)` WITHOUT `self` in the impl; call

//         via `Type::name(...)` with `::`

// When to use: idiomatic "constructor" and utility functions that

// don't need an instance.


struct Point {
  x: float,
  y: float,
}

impl Point {
  // Conventional `new` constructor.

  fn new(x: float, y: float) -> Point {
    return Point { x: x, y: y }
  }
  // Another associated function — origin.



  fn origin() -> Point {
    return Point { x: 0.0, y: 0.0 }
  }

  fn distance(self, other: Point) -> float {
    let dx = self.x - other.x
    let dy = self.y - other.y
    return (dx * dx + dy * dy) ** 0.5
  }
}

// Call with `::` — note the difference from instance method (`.`).

let p = Point::new(3.0, 4.0)
let o = Point::origin()
print(p.distance(o))  // 5

// expected:

// 5

Um tipo pode ter mais de um bloco impl. Todos os blocos se somam: o tipo enxerga todos os métodos definidos em qualquer um deles. Isso permite organizar os métodos por responsabilidade — construtores num bloco, operações geométricas noutro:

Dois blocos impl Vec2: o primeiro define construtores, o segundo operações matemáticas.

05-multiple-impl-blocks.zolo
Playground
// Feature: Multiple `impl` blocks for the same type

// Syntax: several `impl Type { ... }` add up methods

// When to use: organize methods by category (constructors,

// queries, mutations, conversions) or split across logical files.


struct Vec2 {
  x: float,
  y: float,
}

// Block 1: constructors and utility methods.

impl Vec2 {
  fn new(x: float, y: float) -> Vec2 {
    return Vec2 { x: x, y: y }
  }

  fn zero() -> Vec2 {
    return Vec2 { x: 0.0, y: 0.0 }
  }
}

// Block 2: geometric operations.

impl Vec2 {
  fn length(self) -> float {
    return (self.x * self.x + self.y * self.y) ** 0.5
  }

  fn dot(self, other: Vec2) -> float {
    return self.x * other.x + self.y * other.y
  }
}

let v = Vec2::new(3.0, 4.0)
let z = Vec2::zero()
print(v.length())  // 5

print(v.dot(v))  // 25

print(z.length())  // 0

// expected:

// 5

// 25

// 0

Desafio

Adicione um terceiro bloco impl Vec2 com um método normalized(self) -> Vec2 que divide cada componente pelo length() do vetor. Teste com Vec2::new(3.0, 4.0).normalized().

Buscar no Zolo

9 resultados

enespt-br