scalaエイリアスと自己タイプ
4659 ワード
この別名
scalaのソースコードを見ると、多くのソースコードの冒頭にself=>という言葉があります.これはthisにselfという別名をつけたことに相当します.
selfはキーワードではなく、this以外の名前で名前を付けることができます(キーワードを除く).上のコードについては,A内部ではthisで現在のオブジェクトを指すこともselfで表すこともでき,両者は等価である.self=>この書き方は自分のタイプの特殊な方法にすぎない.
自己タイプ(self type)
書式:this:X=>
this:X=>Aがインスタンス化時またはAのサブクラスを定義する際に、指定したXタイプを混入しなければならないことを要求し、このXタイプを現在のタイプとして指定することもできる:
Cのサブクラスを定義際には、自身のタイプの制約によりXタイプも満たさなければならない、すなわちサブクラスもXに混入しなければならない.
scalaの公式サイトの例を見てみましょう.
VerifiedTweeterクラスは、特質Tweeterを拡張するには、特質Userを同時に使用する必要があります.注意深い学生は以上の例が特質traitの中で発生していることに気づいた.scala公式にも自己タイプは特質traitタイプでなければならないことを強調している.つまり
Self-types are a way to declare that a trait must be mixed into another trait, even though it doesn’t directly extend it. That makes the members of the dependency available without imports. https://docs.scala-lang.org/tour/self-types.html
さらにいくつかの例を見てみましょう.
上記の例では、
もう1つの例を見てみましょう.
traitは直接newできませんが、上
参照先:https://www.geeksforgeeks.org/scala-self-types-annotation/https://docs.scala-lang.org/tour/self-types.html http://hongjiang.info/scala-type-system-self-type/http://hongjiang.info/scala-self-type-and-di/https://blog.csdn.net/bluishglc/article/details/60739183
scalaのソースコードを見ると、多くのソースコードの冒頭にself=>という言葉があります.これはthisにselfという別名をつけたことに相当します.
class A {
self => //this
val x=2
def foo = self.x + this.x
}
selfはキーワードではなく、this以外の名前で名前を付けることができます(キーワードを除く).上のコードについては,A内部ではthisで現在のオブジェクトを指すこともselfで表すこともでき,両者は等価である.self=>この書き方は自分のタイプの特殊な方法にすぎない.
自己タイプ(self type)
書式:this:X=>
trait A {
this: X =>
}
this:X=>Aがインスタンス化時またはAのサブクラスを定義する際に、指定したXタイプを混入しなければならないことを要求し、このXタイプを現在のタイプとして指定することもできる:
class A { this:A => }
自己タイプの存在は、現在のクラスを「抽象的」にすることに相当します.これは、自己タイプthis:X=>の存在のため、現在のクラスがインスタンスを構築する際にXタイプを同時に満たす必要があるため、現在のオブジェクト(this)も指定したタイプに合致すると仮定します.scala> new C //
:10: error: class C cannot be instantiated because it does not conform to its self-type C with X
// ok, (C with X)
scala> val c = new C with X
Cのサブクラスを定義際には、自身のタイプの制約によりXタイプも満たさなければならない、すなわちサブクラスもXに混入しなければならない.
scalaの公式サイトの例を見てみましょう.
trait User {
def username: String
}
trait Tweeter {
this: User => // reassign this
def tweet(tweetText: String) = println(s"$username: $tweetText")
}
class VerifiedTweeter(val username_ : String) extends Tweeter with User { // We mixin User because Tweeter required it
def username = s"real $username_"
}
val realBeyonce = new VerifiedTweeter("Beyonce")
realBeyonce.tweet("Just spilled my glass of lemonade") // prints "real Beyonce: Just spilled my glass of lemonade"
VerifiedTweeterクラスは、特質Tweeterを拡張するには、特質Userを同時に使用する必要があります.注意深い学生は以上の例が特質traitの中で発生していることに気づいた.scala公式にも自己タイプは特質traitタイプでなければならないことを強調している.つまり
self:T=>
中のT
traitでなければならない.trait会報でなければclass needs to be trait to be mixed in.
の間違いである.Self-types are a way to declare that a trait must be mixed into another trait, even though it doesn’t directly extend it. That makes the members of the dependency available without imports. https://docs.scala-lang.org/tour/self-types.html
さらにいくつかの例を見てみましょう.
// Scala Program that uses self type
trait with_powers
{
var mind ="extra-ordinary";
}
trait without_powers
{
var mind="ordinary";
}
trait person
{
def brain();
}
// class extend trait
class extraordinary_person extends person
{
// reassign this
this: with_powers =>
override def brain() = println(s"super hero brain is $mind!");
}
// class extend trait
class ordinary_person extends person
{
// reassign this
this: without_powers =>
override def brain() = println(s"normal human brain is $mind.");
}
// Creating object
object GFG
{
// Main method
def main(args:Array[String])
{
val hero = new extraordinary_person() with with_powers;
val mohan = new ordinary_person() with without_powers;
//val mohan= new ordinary_person() with with_powers; ERROR
//does not conform to ordinary_person's self type
hero.brain();
mohan.brain();
}
}
// Output:
// super hero brain is extra-ordinary!.
// normal human brain is ordinary.
上記の例では、
with_powers
、without_powers
、およびperson
といういくつかの特質を作成していますが、extraordinary_person
およびordinary_person
2つのクラスはそれぞれperson
を継承しています.また、2つのクラスはそれぞれ自身のタイプを宣言しています.2つのクラスをインスタンス化する際にはmix in自身のタイプのtraitを必要とします.もう1つの例を見てみましょう.
// Scala Program that uses self type
trait A
{
def x = 1
}
// trait extend another trait
trait B extends A
{
override def x = super.x * 5
}
// trait extend another trait
trait C1 extends B
{
override def x = 2
}
// trait extend another trait
trait C2 extends A
{
this: B=>
override def x = 2
}
// Creating object
object GFG
{
// Main method
def main(args:Array[String])
{
println((new C1 with B).x);
println((new C2 with B).x);
}
}
traitは直接newできませんが、上
(new C1 with B)
withでブレンドタイプオブジェクトを構築し、ブレンドタイプオブジェクトのxを呼び出すべきです.(new C2 with B)
のうちC 2には自己タイプBがあるため、直接Bの中のxの定義が呼び出され、C 2はAから継承するのでsuper.xは実際には2で、結果は10で、興味のある学生は少しデバッグしてみてください.参照先:https://www.geeksforgeeks.org/scala-self-types-annotation/https://docs.scala-lang.org/tour/self-types.html http://hongjiang.info/scala-type-system-self-type/http://hongjiang.info/scala-self-type-and-di/https://blog.csdn.net/bluishglc/article/details/60739183