Equivalencia desde Kotlin
Clases de valor
CercanaUna dataclass congelada distingue EvaluationBudget de int en las anotaciones y genera igualdad por valor. La validación del invariante debe escribirse explícitamente en __post_init__, ya que Python no la deriva automáticamente.
Referencia Kotlin: Declarar un tipo nominal para un dato primitivo y validar su invariante al construirse.
- Mecanismo
- @dataclass(frozen=True) con validación en __post_init__.
- Idea conservada
- El tipo distingue EvaluationBudget de int en las anotaciones, valida el invariante al construirse y genera igualdad por valor.
- Riesgo de diseño
- Confiar solo en las anotaciones de tipo para impedir pasar un int sin validar; Python no las impone en tiempo de ejecución.
- Recomendación
- Valida el invariante en __post_init__ y trata las anotaciones como documentación reforzada por un verificador estático, no como una garantía en tiempo de ejecución.
- Convención del curso
- Valida en __post_init__, no en un método de fábrica aparte.
- Biblioteca estándar
- dataclasses.dataclass(frozen=True).
Diferencias relevantes
- Python no impone el tipo en tiempo de ejecución fuera de esta clase: nada evita construir el dato de otra forma salvo la disciplina y un verificador estático.
- frozen=True impide reasignar remaining después de construir la instancia, pero no impide mutar objetos internos si los hubiera.
__post_init__ valida el invariante tras construir la instancia congelada.
@JvmInline
value class EvaluationBudget(val remaining: Int) {
init {
require(remaining > 0) { "El presupuesto debe ser positivo." }
}
}
val budget = EvaluationBudget(1000) // remaining = 1000from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class EvaluationBudget:
remaining: int
def __post_init__(self) -> None:
if self.remaining <= 0:
raise ValueError("El presupuesto debe ser positivo.")
budget = EvaluationBudget(1000) # remaining = 1000