Geri dönen türler açıkça verilmemişse, Birim döndüren bir yöntem neden String döndüren yöntemle geçersiz kılınabilir?


11

Scala Edition1 Programlama Özellikleri bölümündeki kod örnekleriyle çalışıyordum https://www.artima.com/pins1ed/traits.html

ve yazım yüzünden garip bir davranışla karşılaştım. Kod parçası altındaki bir özellik yöntemini geçersiz kılmasını da geçersiz kılınmış yöntemin dönüş tipleri farklı olmasına rağmen herhangi bir derleme hata vermez Unitvs String. Ancak yöntemi bir nesneye çağırdığınızda Birim döndürür ancak hiçbir şey yazdırmaz.

trait Philosophical {
    def philosophize = println("I consume memory, therefore I am!")
}

class Frog extends Philosophical {
  override def toString = "green"
  override def philosophize = "It aint easy to be " + toString + "!"
}

val frog = new Frog
//frog: Frog = green

frog.philosophize
// no message printed on console

val f = frog.philosophize
//f: Unit = ()

Ancak geçersiz kılınan yöntemde açık dönüş türünü verdiğimde, bir derleme hatası verir:

class Frog extends Philosophical {
  override def toString = "green"
  override def philosophize: String = "It aint easy to be " + toString + "!"
}
         override def philosophize: String = "It aint easy to be " + toString +
                      ^
On line 3: error: incompatible type in overriding
       def philosophize: Unit (defined in trait Philosophical);
        found   : => String
        required: => Unit

Herkes neden derleme hatası ilk durumda açıklamak yardımcı olabilir.


Derleyici, farklı bir sonuç türüne sahip bir yöntemi geçersiz kılmaya çalıştığınız geçerli bir ipucu yazdırdı.
Andriy Plokhotnyuk

Evet, ama benim sorum neden 1. durumda derleyiciden geçti
Shanil

1
Genel kural, her zaman iade türleri konusunda açık olun_ (özellikle genel API'larda) _. Tür çıkarımı yerel değişkenler için harikadır, başka bir şey değildir.
Luis Miguel Mejía Suárez

Yanıtlar:



6

benim sorum neden 1. durumda derleyici geçti

Dönüş türünü açıkça belirtmediğinizde, overrideçalışması için olması gereken tür tarafından çıkarıldı .

Öyle oldu Unit.

Yana Stringdeğerlerin (fonksiyon gövdesini oluşturan ifadesinin değeri) tahsis edilebilir Unit, derleyici mutlu.


1
Şimdi bilmek istediğim, açık dönüş tipinin neden Stringreddedildiğidir. Java'da (ve Scala'da da düşünüyorum), geçersiz kılma sırasında dönüş türünü daraltmanıza izin verilir . Örneğin, üst yöntem döndüğünde Number, geri dönebilirsiniz Integer. Belki void/ Unitözeldir.
Thilo

1
Bu, örneğin derler:trait Philosophical { def philosophize : Number = 1 } class Frog extends Philosophical { override def philosophize : Integer = 2 }
Thilo

2
Dönüş türünü bir alt türe daraltabilirsiniz; ancak bunu yalnızca geçersiz kılınan yöntemin dönüş türüne dolaylı olarak dönüştürülebilecek bir türe daraltamazsınız. Stringiçin Unito olmasa bile, daha ikincisi gibidir aynen böyle.
Alexey Romanov

2
Bayt kodu düzeyinde daralma dönüş türü yoktur, aslında iki yöntem vardır Frog: def philosophize : Integerve def philosophize : Number. İkincisi aslında Philosophical'yöntemini geçersiz kılar (ve birincisini çağırır). Aynı şey kesinlikle voidbaşka bir şey için de yapılabilirdi , tasarımcılar bunu yapmamaya karar verdiler.
Alexey Romanov

2
1. Java da aynısını yapar. 2. Evet, bayt kodunda yapabilirsiniz. Bkz. Örneğin stackoverflow.com/questions/18655541/… ve stackoverflow.com/questions/58065680/… .
Alexey Romanov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.