Me gustaría agregar un método a un tipo incorporado (por ejemplo, Doble), para que pueda usar un operador infix
. ¿Es eso posible?¿Es posible agregar un método a un tipo incorporado en Scala?
Respuesta
Sí y no. Sí, puede hacer que parezca como que ha agregado un método al double
. Por ejemplo:
class MyRichDouble(d: Double) {
def <>(other: Double) = d != other
}
implicit def doubleToSyntax(d: Double) = new MyRichDouble(d)
Este código añade el <>
operador previamente disponible a cualquier objeto de tipo Double
. En tanto que el método doubleToSyntax
está en el ámbito de modo que pudiera ser invocado sin calificación, el siguiente trabajo:
3.1415 <> 2.68 // => true
La parte "no" de la respuesta viene del hecho de que usted no está realmente añadir nada a la clase Double
. En cambio, está creando una conversión de Double
a un nuevo tipo que define el método que desea. Esta puede ser una técnica mucho más poderosa que las clases abiertas que ofrecen muchos lenguajes dinámicos. También pasa a ser completamente seguro para tipos. :-)
Algunas limitaciones que debe tener en cuenta:
- Esta técnica no permite que eliminar o redefinir métodos existentes, sólo tiene que añadir otras nuevas
- El método de conversión implícita (en este caso,
doubleToSyntax
) debe ser absolutamente en-alcance para el método de extensión deseado a estar disponible
idiomático, c implícita las onversiones se colocan dentro de objetos singleton y se importan (p. import Predef._
) o dentro de los rasgos y heredado (por ejemplo, class MyStuff extends PredefTrait
).
Poco a un lado: los "operadores de infijo" en Scala son en realidad métodos. No hay magia asociada con el método <>
que le permite ser infijo, el analizador simplemente lo acepta de esa manera. También puede usar "métodos regulares" como operadores de infijo si lo desea. Por ejemplo, la clase Stream
define un método take
que toma un solo parámetro Int
y devuelve un nuevo Stream
. Esto se puede utilizar de la siguiente manera:
val str: Stream[Int] = ...
val subStream = str take 5
La expresión str take 5
es literalmente idénticos a str.take(5)
.
Esta característica fue práctico para implementar una estimación de error al realizar la clase:
object errorEstimation {
class Estimate(val x: Double, val e: Double) {
def + (that: Estimate) =
new Estimate(this.x + that.x, this.e + that.e)
def - (that: Estimate) =
new Estimate(this.x - that.x, this.e + that.e)
def * (that: Estimate) =
new Estimate(this.x * that.x,
this.x.abs*that.e+that.x.abs*this.e+this.e*that.e)
def/(that: Estimate) =
new Estimate(this.x/that.x,
(this.x.abs*that.e+that.x.abs*this.e)/(that.x.abs*(that.x.abs-that.e)))
def +- (e2: Double) =
new Estimate(x,e+e2)
override def toString =
x + " +- " + e
}
implicit def double2estimate(x: Double): Estimate = new Estimate(x,0)
implicit def int2estimate(x: Int): Estimate = new Estimate(x,0)
def main(args: Array[String]) = {
println(((x: Estimate) => x+2*x+3*x*x)(1 +- 0.1))
// 6.0 +- 0.93
println(((x: Estimate) => (((y: Estimate) => y*y + 2)(x+x)))(1 +- 0.1))
// 6.0 +- 0.84
def poly(x: Estimate) = x+2*x+3/(x*x)
println(poly(3.0 +- 0.1))
// 9.33333 +- 0.3242352
println(poly(30271.3 +- 0.0001))
// 90813.9 +- 0.0003
println(((x: Estimate) => poly(x*x))(3 +- 1.0))
// 27.037 +- 20.931
}
}
Eso es realmente un poco limpio. :) –
- 1. ¿Es posible en Scala obligar al llamante a especificar un parámetro de tipo para un método polimórfico?
- 2. ¿Es posible anular un campo de tipo?
- 3. ¿Es posible agregar un observador a tableView.contentOffset?
- 4. C# ¿Es posible pasar un tipo a un método y hacer que el método devuelva un objeto de ese tipo?
- 5. ¿Cómo alias un tipo incorporado en C#?
- 6. ¿Es posible llamar a un método del tipo que pasa a su método genérico?
- 7. ¿Es posible forzar un tipo a una clase en Haskell?
- 8. ¿Es posible vincular datos a un método en Silverlight?
- 9. ¿Ruby tiene un método string.startswith ("abc") incorporado?
- 10. ¿Es posible agregar un eventlistener en un DIV?
- 11. ¿Hay un tipo de Java incorporado que garantice un método de ejecución (T t)?
- 12. ¿Es posible llamar a un método de espera en un método no asíncrono?
- 13. es posible tener un campo condicional en un tipo anónimo
- 14. Agregar MOQ a un proyecto .NET 4.0 no es posible
- 15. Agregar formulario a un UserControl: ¿es esto posible?
- 16. ¿Es posible agregar comentarios a un archivo csproj?
- 17. ¿Es posible agregar otro elemento a un tipo de enumeración existente?
- 18. Mixin dinámico en Scala - ¿es posible?
- 19. es posible sobrecargar un método final
- 20. ¿Es posible anular un método no virtual?
- 21. ¿Es posible finalizar un método virtual en C#?
- 22. Cómo convertir JSON a un tipo en Scala
- 23. ¿Es posible agregar errores a un objeto ActiveRecord sin asociarlos con un atributo en particular?
- 24. Método Scala @suspendable en un futuro
- 25. ¿Cómo agregar un método a un protocolo existente en Cocoa?
- 26. ¿Hay una función para verificar si un objeto es un tipo de datos incorporado?
- 27. Agregar un atributo mediante programación a un método o parámetro
- 28. ¿Qué es un tipo decimal estándar en Scala 2.9?
- 29. Agregar un tipo MIME en python
- 30. ¿Cómo agregar un constructor a un tipo numérico subclasificado?
Usted puede utilizar la sintaxis class' implícita 'para simplificar esto un poco. – lmm