No oculta la creación de un tipo. Básicamente enmascara el uso de la reflexión para comprobar sus restricciones estructurales en tiempo de compilación e invocar someMethod en el tiempo de ejecución.
Por ejemplo, si usted tiene:
class Foo(t: MyClass {def someMethod:String}) {
def CallSomeMethod = t.someMethod
}
Esto significa que el constructor de la clase Foo acepta una camiseta de MiClase tipo que también tiene un algunMetodo (donde el algunMetodo podría ser mezclado en MiClase a través de un rasgo). Usted podría tener:
class MyClass {}
trait WithSomeMethod {def someMethod = "hello"}
y, a continuación, podría crear Foo así:
val mc = new MyClass with WithSomeMethod
val foo = new Foo(mc)
println(foo.CallSomeMethod) // prints "hello"
ahora, cuando se crea new Foo(mc)
el compilador utiliza la reflexión para comprobar que mc es un MiClase que también tiene un algunMetodo . La llamada real foo.CallSomeMethod
también funciona a través de la reflexión.
ahora (toleradme, Estoy llegando a su pregunta real ...) haciendo como lo hizo:
type T = MyClass {def someMethod:String}
sólo se está creando un alias de tipo, no un tipo concreto. Una vez que tenga T define de esa manera, se puede definir como Foo:
class Foo(t: T) {
def CallSomeMethod = t.someMethod
}
esto es equivalente a la definición de Foo dada anteriormente. Acabas de crear un alias T que se puede reutilizar en otros lugares donde podrías haber usado MyClass {def someMethod:String}
. No se genera ningún tipo de T real y el compilador todavía usa la reflexión cada vez que se refiere a T, para comprobar la restricción estructural que tiene un Método algo definido, y aún genera código basado en la reflexión para invocar algún Método.
Gracias, entonces el uso de tal restricción estructural tan lenta como la reflexión en java? Y el rasgo es una mejor opción en esa luz. – yura
sí, los tipos estructurales tienen un impacto en el rendimiento debido a la reflexión. –