문제

스칼라에서는 구조물을 보았습니다

trait T extends S

그리고

trait T { this: S =>

비슷한 것을 달성하는 데 사용됩니다 (즉, 추상적 인 방법은 S 인스턴스가 생성되기 전에 정의해야합니다). 그들의 차이점은 무엇입니까? 왜 하나를 사용 하시겠습니까?

도움이 되었습니까?

해결책

의존성 관리를 위해 자체 유형을 사용합니다.이 특성은 다른 특성을 혼합해야합니다. 그리고 상속을 사용하여 다른 특성이나 인터페이스를 개선 할 것입니다.

예를 들어 :

trait FooService

trait FooRemoting { this : FooService => }
trait FooPersistence { this : FooService => }

object Services extends FooService with FooRemoting with FooPersistence

이제 fooremoting과 foopersistence가 모두 fooservice에서 물려 받았을 것이고 Fooservice가 멤버와 방법을 가지고 있다면 서비스는 어떻습니까?

상속을 위해서는 다음과 같은 것이 있습니다.

trait Iterator[T] {
  def hasNext : boolean
  def next : T
}

trait InfiniteIterator[T] extends Iterator[T] {
  def hasNext = true
}

다른 팁

자체 유형 주석을 사용하면 주기적 종속성을 표현할 수 있습니다. 예를 들어:

trait A extends B
trait B { self: A => }

이것은 간단한 상속으로 불가능합니다.

질문을 묻는 이후로 나는이 게시물을 발견했다.

스피로스 Tzavellas 특성을 공개 인터페이스로 사용하고 자체 유형을 구현 클래스에서 혼합 해야하는 도우미로 사용하는 것에 대해 이야기합니다.

결론적으로, 우리가 특성 내부의 방법 구현을 이동하려면, 우리는 구체적인 방법의 구현을 지원하고 특성의 주요 책임과 관련이없는 추상 방법으로 해당 특성의 인터페이스를 오염시키는 위험이 있습니다. 이 문제에 대한 해결책은 이러한 추상적 인 방법을 다른 특성으로 이동시키고 자기 유형 주석과 다중 상속을 사용하여 특성을 함께 구성하는 것입니다.

예를 들어:

trait PublicInterface { this: HelperTrait =>
  // Uses helperMethod
}

trait HelperTrait {
  def helperMethod = // ...
}

class ImplementationClass extends PublicInterface with HelperTrait

스칼라 투어 추상 유형 멤버와 자체 유형 주석을 사용하는 것에 대해 논의합니다. extend 추상 유형 멤버 (?)

대답은 "원형"입니다. 그러나뿐만 아니라.

자체 유형 주석은 나에게 상속의 근본적인 문제를 해결합니다. 자체 유형을 사용하면 모든 것이 쉬워집니다.

내 패턴은 다음과 같은 것이며 퇴화 된 케이크로 간주 될 수 있습니다.

trait A { self: X => def a = reuseme}
trait B { self: X => def b = a }
class X extends A with B { def reuseme=null }

깨끗하게 입력하면서 조립품의 어느 곳에서나 호출 할 수있는 여러 행동으로 수업을 폭발시킬 수 있습니다. 케이크 패턴으로 너무 자주 (그리고 잘못) 고통스러운 간접이 필요하지 않습니다.

지난 10 년간의 복잡한 Java di 프레임 워크의 절반 (총이 아닌 경우)은 물론 타이핑 없이이 작업을 수행하는 데 전념했습니다. 이 도메인에서 여전히 Java를 사용하는 사람들은 "Scala Ouakbar"라는 시간을 분명히 잃고 있습니다.

나는이 질문이 오래되었다는 것을 알고 있지만 설명과 예제를 추가하고 싶습니다.

특성 상속과 자기 유형에는 세 가지 주요 차이점이 있습니다.

의미론

상속은 대상 패러다임의 가장 결합 된 관계 중 하나이며, A가 B를 연장하면 A는 A가 B임을 의미합니다.

다음 코드가 있다고 가정 해 봅시다.

trait Animal {
  def stop():Unit = println("stop moving")
}

class Dog extends Animal {
  def bark:String = "Woof!"
}

val goodboy:Dog = new Dog

goodboy.bark
// Woof!

우리는 개가 말하고 있습니다 ~이다 동물. 메시지를 보낼 수 있습니다 bark 그리고 stop 에게 goodboy 개이기 때문에 두 가지 방법을 모두 이해합니다.

이제 우리가 새로운 특성을 가지고 있다고 가정 해

trait Security {
  this: Animal =>
  def lookout:Unit = { stop(); println("looking out!") }
}

이번에 보안은 동물이 아니며, 보안이 동물임을 확인하면 의미 적으로 부정확하기 때문에 괜찮습니다. 그들은 서로 다른 개념이며 함께 사용할 수 있습니다.

이제 우리는 새로운 종류의 개를 만들 수 있습니다.

val guardDog = new Dog with Security

guardDog.lookout
// stop moving
// looking out!

guardDog 개, 동물 및 안전입니다. 이해합니다 stop, bark 그리고 lookout 보안이있는 개이기 때문입니다.

그러나 우리가 이와 같은 새 개를 만들면 어떻게됩니까?

val guardDog2:Dog = new Dog with Security
guardDog2.lookout // no such method!

guardDog2 단지 개이므로 우리는 전화 할 수 없습니다 lookout 방법. (Okok, 그것은 보안이있는 개이지만 우리는 단지 개를 본다)

주기적 종속성

자체 유형을 사용하면 유형간에 순환 종속성을 만들 수 있습니다.

trait Patient {
  this: Reader =>
  def isQuite:Boolean = isReading
  def isSlow:Boolean = true
}

trait Reader {
  this: Patient =>
  def read():Unit = if(isSlow) println("Reading Slow...") else println("Reading Fast...")
  def isReading = true
}

val person = new Patient with Reader

다음 코드는 컴파일되지 않습니다.

trait Patient extends Reader { /** code **/}

trait Reader extends Patient { /** code **/ }

이러한 종류의 코드는 종속성 주입 (케이크 패턴)에서 매우 일반적입니다.

다재

마지막으로, 우리의 특성을 사용하는 사람은 사용 된 순서를 결정할 수 있으므로 특성 선형화 덕분에 사용 된 특성이 동일하지만 최종 결과는 다를 수 있습니다.

정상적인 상속을 통해 우리는 그렇게 할 수 없으며, 특성과 계급 간의 관계는 고정되어 있습니다.

trait Human {
  def isGoodForSports:Boolean
}

trait Programmer extends Human {
  def readStackOverflow():Unit = println("Reading...")
  override def isGoodForSports: Boolean = false
}

trait Sportsman extends Human {
  def play():Unit = println("Playing something")
  override def isGoodForSports: Boolean = true
}

val foo = new Programmer with Sportsman
foo.isGoodForSports
// true

val bar = new Sportsman with Programmer
bar.isGoodForSports
// false

이것이 유용 할 수 있기를 바랍니다.

그것은 당신의 질문에 대답하지는 않지만, 나는 자기 유형 주석을 이해하려고 노력했고 기본적으로 답을 잃어 버렸고, 어떻게 든 당신의 질문의 변형을 순환하게되었으며, 이는 의존성을위한 자기 유형 주석 사용에 중점을 둡니다.

그래서 여기에 나는 자기 유형 주석이 잘 설명 된 사용 사례에 대한 설명, 즉 하위 유형으로 'this'의 유형 안전 사례와 같은 설명을 게시합니다.

http://programming-scala.labs.oreilly.com/ch13.html#selftypeannotationsandabstracttypemembers

우연히이 질문에 참여하는 사람들에게 도움이되기를 바라고 있습니다 (그리고 나처럼, 탐험하기 전에 스칼라 책을 읽을 시간이 없었습니다 :-))).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top