2014-08-28 43 views
8

Bu neden derlenmiyor?
verilen hata SomeElement üzerinde tanımlı yöntem eval tip kısıtlamaları tatmin etmiyor neden anlayamıyorum class SomeElement needs to be abstract, since method eval in trait Element of type [T <: Typed]=> scala.util.Try[T] is not definedNeden scalac bir yöntemin gerekli tip imzasına uymadığına inanmıyor?

olduğunu.

Anladığım kadarıyla TryTry numaralı alt öğeleri içeren Typed alt sınıflarını döndürmelidir. Tür parametresinde eşdeğerdir. SomeElement'da eval'un uygulanması, NumberLike ve NumberLike alt sınıflarını Typed döndürür. Peki yanlış giden neydi?

import scala.util.Try 

trait Element { 
    def eval[T <: Typed]: Try[T] 
} 

trait Typed 

case class NumberLike(n: Long) extends Typed 

case class SomeElement(n: Long) extends Element { 
    def eval = Try { 
    NumberLike(n) 
    } 
} 

object app extends Application { 
    println (SomeElement(5).eval) 
} 

ya SomeElement yılında eval açık tip parametre eklemek çalışıyorum yardımcı değildir:

case class SomeElement(n: Long) extends Element { 
    def eval[NumberLike] = Try { 
    NumberLike(n) 
    } 
} 

yukarıda SomeElement ait Definition değiştirme verir:

found : <empty>.NumberLike 
    required: NumberLike(in method eval) 
    NumberLike(n) 

EDIT'u neden nu derlemediğini bilmek isterim. Sorun için geçici çözümler yardımcı olabilir, ancak gerçekten burada neler olduğunu bilmek istiyorum.

+1

Yapamam tercih Şimdi tam bir cevap yazın, ancak kesinlikle, işlevsiz işlevle poli işlevini geçersiz kılmaya/uygulayamazsınız; bu yüzden “def eval [T: NumberLike] =…” gibi bir yazı yazmak zorundasınız. ” – DaunnC

+0

Neden“ soyut özellik ”? – cchantep

+0

@DaunnC düzenleme – Squidly

cevap

2

tür parametresi T olmayan parça tip Element üzerinde, işlevi tanımlanır, bu miras ile 'silinir' edilemez ve geçersiz kılma fonksiyonu (http://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#class-members) üzerinde tutulmalıdır.

Tür parametresini Element tanımına göre hareket ettirin, aşağıdaki gibi çalışmasını sağlayın.

trait Element[T <: Typed] { 
    def eval: Try[T] 
} 

trait Typed 

case class NumberLike(n: Long) extends Typed 

case class SomeElement(n: Long) extends Element[NumberLike] { 
    def eval = Try { 
    NumberLike(n) 
    } 
} 

Veya bir tür eleman kullanılarak: Birisi bir çözüm vermiştir

trait Element { 
    type T <: Typed 
    def eval: Try[T] 
} 

trait Typed 

case class SomeElement(n: Long) extends Element { 
    type T = NumberLike 
    def eval = Try { 
    NumberLike(n) 
    } 
} 
+0

Bu Elementi genişleten her şeyin Eleman için bir tip parametresi sağlaması gerektiği anlamına gelir. – Squidly

+1

Ya, ya da bir tür üye kullanarak (bkz. Düzenleme) – cchantep

+0

Ikinci olanı tercih ederim. Bence T <: Typed '' yi hazırlamalıdır. – Squidly

0

beri, nedenini açıklamaya çalışıyorum. java olarak

, böyle bir şey yasadışı:

class A { 
    <T> T f() {return null;} 
    Object f() {return null;} 
} 

Ama scala içinde, ki yasal:

class A { 
    def f[T](): T = ??? 
    def f(): Any = ??? 
} 

temel fark şudur: aynı ad ve parametreler listesi ile scala tedavi 2 yöntem Biri tip parametresi ve başka bir yok ise farklı (scala yöntemi imzası türü parametreleri içerir, yanlış olsaydı beni düzeltin :))

Sizin durumda, Eğer normal yöntemle tipi parametresi olan bir yöntem üzerine yazamazsınız. (farklı imzalar var)

Ben, hangisi daha iyi emin değilim şahsen scala kuralı :)

İlgili konular