2016-03-01 28 views
9

Uygulamanın aşırı yük çözünürlüğü ile belirlendiği basit bir fabrika modeline sahibim. Sorun, Kotlin derleyicisinin inline lambda için "Aşırı yük çözünürlüğü belirsizliği" ile ilgili şikâyette bulunması.Kotlin: Inline lambda ve aşırı yük çözünürlüğü belirsizliği

class Foo(){ 
    companion object Factory { 
     fun create(x: Int, f: (Int) -> Double) = 2.0 
     fun create(x: Int, f: (Int) -> Int) = 1 
    } 
} 

fun main(args:Array<String>){ 
    val a = Foo.create(1,::fromDouble) //OK 
    val b = Foo.create(1,::fromInt) //OK 
    val ambiguous = Foo.create(1){i -> 1.0} //Overload resolution ambiguity? 
} 


fun fromDouble(int:Int) = 1.0 
fun fromInt(int:Int) = 1 
Kotlin derleyici çözmek aşırı yük çözünürlük neden satır içi lambda belirsiz olarak kabul edilir ve yok nasıl

?

+4

Bu bir hata gibi görünüyor, çünkü eğer lambda'yı “Int (Int) -> Double” gibi (Int) -> Double (Çift) olarak çevirirseniz, hiçbir belirsizlik olmaz, ancak cast gerekmediğini söylüyor. Ayrıca, lambda'yı "val l = {i: Int -> 1.0}' a ayıklayıp kullanırsam, yine bir belirsizlik olmaz. Lütfen bu sorun için hata izleyicide arama yapın ve eğer yeni bir dosya yoksa yeni bir dosya gönderin: https://youtrack.jetbrains.com/issues/KT – hotkey

+1

Bir başka ilginç şey, lambda'yı @hotkey yaparsanız, IDE Bu gerekli değil. Ama onu kaldırdığın an, belirsizlikten şikayet ediyor. –

+1

Giriş için teşekkürler! Muhtemelen bir böcek olduğunu düşündüm. Https://youtrack.jetbrains.com/issue/KT-11265 –

cevap

4

Kotlin derleyici her ifadeyi yalnızca bir kez çözer. Yani derleyici, lambda ifadesi için çözünürlüğü başlattığında, lambda argümanlarının türlerini bilmelidir. Bu derleyici nedeniylecreateyöntemlerinden birini seçmeniz gerekir lambda içine bakmaya başlar.

Örnek:

İşte
fun foo(f: (Int) -> Int) = 1 
fun foo(f: (String) -> String) = "" 
val bar = foo { 
    println(it) 
    5 
} 

bunlardan hiç kimse başka o daha spesifik olduğu için biz fonksiyonların foo birini seçemezsiniz, bu yüzden biz bilmiyoruz çünkü biz lambda ifadesi için çözünürlüğü başlayamaz it için yazın. Örneğinizde, lambda için belirli bir işlevi seçmeden önce teoriyi kurabilmeniz mümkündür, çünkü tüm potansiyel fonksiyonlar için lambda argümanları aynıdır. Fakat uygulanması zor olan mantıksız bir mantıktır.

+0

bir rapor Filed Bu bir bummer. Lambda üzerinde aşırı çözünürlük, sayısal uygulama için çok kullanışlıdır. Float, double ve int üzerinde çalışan bir matris sınıfım olduğunu varsayalım. "Aşırı yükleme çözünürlüğü" ile, "msg = Mat44 {i, j -> 1.0}' dır, şimdi "val ms = Mat44 ({i: Int, j: Int -> 1.0} as) yazmam gerekiyor Int, Int) -> Double (Çift) 'dır, böylesi önemsiz bir görev için sade ve aptalca bir ayrıntıdır. Büyük bir açıklama için çok teşekkürler @erokhins! –

+0

Geçici çözüm olarak farklı isimlerle fonksiyonlar oluşturabilirsiniz: 'eğlenceli Mat44Int2Double (f: (Int, Int) -> Çift) = Mat44 (f)'. Ama zarif değil ... – erokhins

+0

Evet, iyi eski ANSI C günlerini hatırlatıyor :) –

İlgili konular