コトリンが吸う理由

この記事は、この記事に基づいてハーフジョークとして生まれました。 その記事では、ほとんどの「問題」は合成されており、非常にまれにしか使用されないか、著者の意見ではその言語が対応すべき理論的パラダイムに一致する言語の期待のために大げさです。 一方、私の人生を本当に複雑にするものは、個人的には言及されていません。







Kotlin



, . , , .







for



for



Kotlin



, Kotlin



.







inline fun <T> For(it : Iterator<T>, cb : (T) -> Unit) {
  while (it.hasNext()) cb(it.next())
}

fun main(a : Array<String>) {
  val list = listOf(1, 3, 4, 12)
  println("for");   for (it in list) println(it)
  println("FOR");   For(list.iterator()) { println(it) }

  val arr = arrayOf(1, 3, 4, 12)
  println("a-for"); for (it in arr) println(it)
  println("a-FOR"); For(arr.iterator()) { println(it) }

  println("r-for"); for (it in 0..10) println(it)
  println("r-FOR"); For((0..10).iterator()) { println(it) }
}
      
      





For



for



, . , .







: ? .







, for



-, . . , , - , while



-.







- null-



- , , - , 25



, (sic!) void*



, : " " " ". , . , , ?







null-safety



Kotlin



-, ? null



, Java



, Kotlin



, , . , ? . , .







, . - - , ? null



, . , Kotlin



.







var value : Int? = null

fun F() : Int {
  if ( value != null ) return 0
  return value // 
}
      
      





Smart cast to 'Int' is impossible, because 'value' is a mutable property that could have been changed by this time . - - .







, ??!!! ? , — ? , - .







? ! . . . . , "" .







var value : Int? = null

fun F() : Int {
  if (value == null) return 0
  return when (Random().nextInt()) {
    3    -> value!! + 2
    12   -> value!! + 1
    5    -> value!! * 4
    else -> 0
  }
}
      
      





, "" , . , null



— "" , .







null



, . , " - ".







, .







Java







public class jHelper {
  public static jHelper jF() { return null; }
  public void M() {}
}
      
      





Kotlin







fun F() {
  val a = jHelper.jF()
  a.M()  //!
}
      
      





- , c NullPointerException



.. Kotlin



. ..., , ?







, :









.. , , . , !







.







— ?



if



, , . ?







var value = 10

fun F() : Int {
  return value = 0 // 
}
      
      





:







var v1 = 1
var v2 = 1
var v3 = 1

fun F() {
  v1 = v2 = v3 = 0 // 
}
      
      





? , , . if (v=20)



?.. , , .. , Kotlin



, -, . . ?







"?:"?



"?:"?







?







value != 0 ? "Y" : "N"
      
      





if



:







if (value != 0) "Y" else "N"
      
      





( ?) , if () else



, .







?



, — . , , . , , . - ?! , ?







, . Pascal



. - «there are no implicit widening conversions for numbers»? "are no", ?







val i = 10
val l = 12L
val f = 12.1

val l1 = i+100/l-f
      
      





?!







val l1 = i.toDouble() + 100.toDouble() / l.toDouble() - f
      
      





.. - … … - … … . — . , , Int



Long



, Float



Double



.







, .







:







val c : SomeClass? = null

if ( c ) "not-null"
if ( !c ) "is-null"
      
      





.. .







-typedef



Kotlin



. . , , . — , … -.







- . :







  1. . , , - . .







  2. . .. . , .







  3. . . ( .1), .. , , () . .


:







typealias aI = SuperPuperClassA
typealias pSI = Pair<String,Int>
typealias pIS = Pair<Int,String>
typealias pOTHER = Pair<String,Int>
typealias aS = List<String>

class SuperPuperClassA {
  fun F() = pSI("",10)
}

fun main(a : Array<String>) {
  val a = aI()
  val i1 = a.F()
  val i2 : Pair<*,*> = a.F()
  val i3 : Any = a.F()

  //     
  if ( i1 is pSI ) println("ok")
  if ( i1 is pOTHER ) println("ok")

  //   
  if ( i1 is pIS ) println("not compile")
  if ( i2 is pSI ) println("not compile")
  if ( i2 is pIS ) println("not compile")
  if ( i3 is pSI ) println("not compile")
  if ( i3 is pIS ) println("not compile")
}
      
      





, . .. , . , Kotlin



, ( ), , , .







, , : "Cannot check for instance of erased type". ( ) JVM



.







.







, . - .







, , , ?







Nested and local type aliases are not supported









, , .. private



"" .









(generics) Java



Kotlin



: JVM



.







Java



.. . Kotlin



, , Java



, , .







() - .. , .







:







/*00*/ class C<T>(val value : Any) {
/*01*/   fun F() : T {
/*02*/     try {
/*03*/       val v = value as T //  "Unchecked cast: Any to T"
/*04*/       return v
/*05*/     } catch(ex : RuntimeException) {
/*06*/       println("Incompatible")
/*07*/       //    ,        
/*08*/       return 0 as T
/*09*/     }
/*10*/   }
/*11*/ }
/*12*/ 
/*13*/ fun fTest() {
/*14*/   val a = C<Int>( 12.789 )
/*15*/   println( "rc: ${a.F()}" )
/*16*/ 
/*17*/   val b = C<Int>( "12.123" )
/*18*/   println( "rc: ${b.F()}" )
/*19*/ }
      
      





, "" .







, : ?







:







  1. , "12", "12"
  2. , "12", "Incompatible"
  3. , "12.789", "12.123"
  4. "C::F" ( ?)
  5. "fTest" ( ?)


: "fTest" 18







rc: 12

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
    at jm.test.ktest.KMainKt.fT(kMain.kt:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
      
      





: ?







  1. , Double



    Int



    ?
  2. try



    /catch



    ?
  3. "C::F"?


, .







, Kotlin



"C::F":







// val v = value as T

GETFIELD jm/test/ktest/C.value : Ljava/lang/Object;
CHECKCAST java/lang/Object
ASTORE 1
      
      





( ), CHECKCAST Object



. .. , .







, "C::F":







LINENUMBER 18 L6
ALOAD 1
INVOKEVIRTUAL jm/test/ktest/C.F ()Ljava/lang/Object;
CHECKCAST java/lang/Number
      
      





-, ( ), , . : Kotlin



, , .







, Kotlin



, .







: Java



. , , , … — VCL



. Borland



-,



Pascal



RTTI



, . , Java



, Kotlin



- . . , , , - , Java



.







Java



.







public class jTest<T> {
  Object value;

  jTest( Object v ) { value = v; }

  public T F() { return (T)value; } //  "Unchecked cast"

  public static void Test() {
    jTest<Integer> a = new jTest<Integer>( 12.123 );
    System.out.print( "rcA: " );
    System.out.print( a.F() );

    jTest<Integer> b = new jTest<Integer>( "12.789" );
    System.out.print( "\nrcB: " );
    System.out.print( b.F() );

    System.out.print( "\n" );
  }
}
      
      





Kotlin



Java



.







fun fTJ_1() {
  val a = jTest<Int>( 12.123 )
  println( "rc: ${a.F()}" )

  val b = jTest<Int>( "12.789" )
  println( "rc: ${b.F()}" )
}

fun fTJ_2() {
  jTest.Test()
}
      
      





: , :







  1. Kotlin



    ;
  2. Java



    , Kotlin



    ;
  3. Java



    ;


?







:









:







  1. Kotlin



    :







    rc: 12
    Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
          
          





  2. Kotlin->Java



    :







    Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
          
          





  3. Java



    :

    rcA: 12.123
    rcB: 12.789
          
          





? .









( Java, Scala, Groovy Lua , , ++) , .







Kotlin



— , . ( ) : listOf, mapOf arrayOf.







, - :







  val iArr1 = arrayOf(1, 2, 3)
  val iArr2 = arrayOf( arrayOf(1, 2, 3), arrayOf(1, 2, 3), arrayOf(1, 2, 3) )
  val iArr3 = arrayOf(
    arrayOf(arrayOf(1, 2, 3), arrayOf(1, 2, 3), arrayOf(1, 2, 3)),
    arrayOf(arrayOf(1, 2, 3), arrayOf(1, 2, 3), arrayOf(1, 2, 3)),
    arrayOf(arrayOf(1, 2, 3), arrayOf(1, 2, 3), arrayOf(1, 2, 3))
    )
      
      





:







  val tree = mapOf(
    Pair("dir1", mapOf(Pair("file1", 0), Pair("file2", 1))),
    Pair("dir2", mapOf(
      Pair("dir21", mapOf(Pair("file1", 0), Pair("file2", 1))),
      Pair("dir22", mapOf(Pair("file1", 0), Pair("file2", 1))))) )
      
      





, - .







, ( JSON ), ...







  1. , — - ( ).
  2. , , .
  3. , , .


, — , .







: - . Array<Array<Array<Array<Double>>>>



Array<Array<Array<Double>>>



.








All Articles