Funciones Asociadas y Múltiples Bloques impl
En esta página
Las funciones asociadas se definen en impl pero no reciben self — no
necesitan una instancia para ser invocadas. El idioma estándar es usar new
(o cualquier nombre descriptivo) como constructor. La llamada usa :: en lugar
de .:
Point::new(x, y) y Point::origin() son funciones asociadas; distance es un método de instancia.
// 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
Un tipo puede tener más de un bloque impl. Todos los bloques se suman: el
tipo ve todos los métodos definidos en cualquiera de ellos. Esto permite organizar
los métodos por responsabilidad — constructores en un bloque, operaciones
geométricas en otro:
Dos bloques impl Vec2: el primero define constructores, el segundo operaciones matemáticas.
// 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
Desafío
Agrega un tercer bloque impl Vec2 con un método normalized(self) -> Vec2 que
divida cada componente por el length() del vector. Pruébalo con
Vec2::new(3.0, 4.0).normalized().
Consulta también