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) { }
}
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
.
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)
}
}
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);
}
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.
Je pense que cela peut vous aider:
input.buffered(1024).reader().forEachLine {
fos.bufferedWriter().write(it)
}
la manière simple à Kotlin est
if (kotlin.run{ a=b; a != c}){ ... }