Soru Nedir ?. Bir görevin sol tarafında kullanıldığında Kotlin'de mi demek istiyorsun?


Göre Kotlin dokümanlar? operatör bir 'güvenli çağrı' temsil eder, yani bir yöntem çağrıları zincirinde kullanılırsa, kullanılan zincirin değeri boşsa, tüm zincir sıfırlanır.

Peki ya ödevin sol tarafında kullanılıyorsa? Sol taraf, 'geri dönen' bir şey olmadığından, muhtemelen farklı bir etkiye sahip gibi görünüyor. İşte bahsettiğim şeyin bir örneği:

val myObj = SomeObj()
myObj?.property = SomeClass.someFunc() // What does ?. do in this context?

21
2018-06-16 13:37


Menşei




Cevaplar:


Bu, sol taraftaki güvenli çağrılardan birinin başarısız olması durumunda (yani alıcının boş olması), tüm atamanın atlanması ve sağ taraftaki ifadenin hiç değerlendirilmemesi anlamına gelir.

val nullable: Container? = null
nullable?.x = f() // f is not called

(çalıştırılabilir demo)


27
2018-06-16 13:40



Bu ilginç bir şey çünkü kendi başına bir değere bir şey atadığınız durumda, derleyici hatasından kaçınmak için onu da sağ tarafta kullanmak zorundasınız. (ör. myObj? .property = myObj? .property + 1) - Sonofblip
@Sonofblip, bunun için farklı bir neden var: çok parçalı bir ortamda (bir JVM olan), global bir değişken myObj Sol taraftaki çek ve değerlendirme arasında yeniden tayin edilebilir. myObj?.property sağ tarafta. Yani, tekrar kontrol etmelisin. - hotkey
@ holi-java, lütfen bakın bu durumBir satır için üretilen bayt kodunu açıkladım. c?.x = (c?.x ?: 0) + 1. Bunu açıkça görebiliyorsun AppKt.c iki kez erişilir, yani c Arasında yeniden atandığında, ikinci aramada boş bir değer alabilirsiniz. Bu nedenle derleyici buna c sağ tarafta null olarak, ve tekrar kullanabilmeniz için boş kontrol etmelisiniz. Demek istediğim şey o. - hotkey
@ holi-java, demek istediğim c null, Kotlin derleyicisi yazmanıza izin vermiyor c?.x = c.x + 1, Çünkü c iki kez erişilir ve arasında yeniden kullanılabilir. Tarafından 'Kontrol'Demek istedim, güvenli erişimi kullanman gerek ?. yine sağ tarafta, gibi (c?.x ?: 0) + 1veya null olmayan bir iddiada bulun !!, sevmek c!!.x + 1. - hotkey
@hotkey Üzgünüm, detaylı yorumunuzla ne söylediğinizi anlıyorum. çok teşekkürler. - holi-java


Şimdi Kotlin'de eğlenceli bir soru ve cevap görüyorum. Cevap çok güzel olsa bile, ama daha ayrıntılı olarak açıklığa kavuşturmak istiyorum.

Aşağıdaki atama ifadesi:

myObj?.property = SomeClass.someFunc() 

aşağıdaki gibi Kolin tarafından Java bytecode dönüştürülür:

val it = myObj;

if(it != null){
   it.property = SomeClass.someFunc(); 
}

Yani birden çok iş parçacığında sorun yoktur. Hala iyi çalışıyor ve test ettim github. Ama sonuçta İplik paraziti sorun, yani property farklı referanslarda myObj değişti.

Atama ifadesi dışında kısa devrediğerleri de olabilir kısa devre. Örneğin:

val array:Array<Any>? = null;

//   v--- short-circuited
array?.set(0,SomeClass.someFunc());
//                     ^--- never be called

2
2018-06-16 17:52