web-dev-qa-db-fra.com

Comment convertir une expression d'affectation Java en Kotlin

Quelque chose à Java comme 

int a = 1, b = 2, c = 1;
if ((a = b) !=c){
    System.out.print(true);
}

maintenant il devrait être converti en kotlin comme

var a:Int? = 1
var b:Int? = 2
var c:Int? = 1
if ( (a = b) != c)
    print(true)

mais ce n'est pas correct.

Voici l'erreur que je reçois:

in " (a=b)" Error:(99, 9) Kotlin: Assignments are not expressions, and only expressions are allowed in this context

En réalité, le code ci-dessus n'est qu'un exemple pour clarifier le problème. Voici mon code original:

fun readFile(path: String): Unit { 
    var input: InputStream = FileInputStream(path) 
    var string: String = "" 
    var tmp: Int = -1 
    var bytes: ByteArray = ByteArray(1024) 

    while((tmp=input.read(bytes))!=-1) { } 
}
24
K.K Song

Comme @AndroidEx a été correctement déclaré, les assignations ne sont pas des expressions dans Kotlin, contrairement à Java. La raison en est que les expressions ayant des effets secondaires sont généralement découragées. Voir cette discussion sur un sujet similaire.

Une solution consiste simplement à scinder l'expression et à déplacer le bloc d'affectation en dehors de l'affectation:

a = b
if (a != c) { ... }

Une autre consiste à utiliser des fonctions de stdlib telles que let , qui exécute le lambda avec le récepteur en tant que paramètre et renvoie le résultat lambda. apply et run ont une sémantique similaire.

if (b.let { a = it; it != c }) { ... }

if (run { a = b; b != c }) { ... }

Grâce à inlining , cela sera aussi efficace qu’un code simple pris dans le lambda.


Votre exemple avec InputStream ressemblerait à

while (input.read(bytes).let { tmp = it; it != -1 }) { ... }

En outre, considérez readBytes function pour lire une ByteArray à partir d'une InputStream.

26
hotkey

Les devoirs ne sont pas des expressions dans Kotlin, vous devrez donc le faire à l'extérieur:

var a: Int? = 1
var b: Int? = 2
var c: Int? = 1

a = b
if (a != c)
    print(true)

Pour votre autre exemple avec InputStream, vous pourriez faire:

fun readFile(path: String) {
    val input: InputStream = FileInputStream(path)
    input.reader().forEachLine {
        print(it)
    }
}
11
AndroidEx

Comme presque tout le monde ici l'a souligné, les tâches ne sont pas des expressions en kotlin. Cependant, nous pouvons contraindre l'affectation dans une expression à l'aide d'un littéral de fonction:

val reader = Files.newBufferedReader(path)
var line: String? = null
while ({ line = reader.readLine(); line }() != null) {
    println(line);
}
7
w.brian

Java: (a = b) != c

Kotlin: b.also { a = it } != c


_ {Autour de la question d'OP} _

Contrairement à réponse acceptée , je suggère d'utiliser la fonction also de Kotlin, au lieu de let:

while (input.read(bytes).also { tmp = it } != -1) { ...

Parce que T.also renvoie T (it) lui-même, vous pouvez ensuite le comparer avec -1. Cela ressemble plus à l'affectation de Java en tant qu'énoncé.


Voir la section "Renvoyer ce type par rapport à un autre type", sur ce blog utile pour plus de détails.

2
Mir-Ismaili

Je pense que cela peut vous aider:

 input.buffered(1024).reader().forEachLine {
            fos.bufferedWriter().write(it)
        }
0
user2944157

la manière simple à Kotlin est

if (kotlin.run{ a=b; a != c}){ ... }
0
Ara Hakobyan