Comment renvoyer 3 valeurs de données distinctes du même type (Int) à partir d'une fonction dans Kotlin?
J'essaie de renvoyer l'heure du jour, j'ai besoin de renvoyer l'heure, la minute et la seconde sous forme de nombres entiers séparés, mais tout en un va de la même fonction, est-ce possible?
Dans Swift nous le faisons comme suit,
func getTime() -> (Int, Int, Int) {
...
return ( hour, minute, second)
}
pouvons-nous y parvenir à Kotlin?
P.S: Je sais que je peux utiliser Array ou Hashmap pour cela, mais je veux savoir s’il existe quelque chose dans kotlin comme dans Swift.
Vous ne pouvez pas créer de nuplets arbitraires dans Kotlin, vous pouvez utiliser classes de données . Une option consiste à utiliser les classes Pair
et Triple
intégrées qui sont génériques et peuvent contenir deux ou trois valeurs, respectivement. Vous pouvez les combiner avec déclarations de déstructuration comme ceci:
fun getPair() = Pair(1, "foo")
val (num, str) = getPair()
Vous pouvez également déstructurer un List
ou Array
, jusqu'au premier (5 éléments :
fun getList() = listOf(1, 2, 3, 4, 5)
val (a, b, c, d, e) = getList()
La manière la plus idiomatique serait toutefois de définir votre propre classe de données, ce qui vous permettra de renvoyer un type significatif à partir de votre fonction:
data class Time(val hour: Int, val minute: Int, val second: Int)
fun getTime(): Time {
...
return Time(hour, minute, second)
}
val (hour, minute, second) = getTime()
Il semble que vous ayez conscience de la solution évidente consistant à créer une classe spécifique pour gérer le temps. Donc, je suppose que vous essayez d'éviter le petit souci de créer une classe, d'accéder à chaque élément d'un tableau, etc., et de rechercher la solution la plus courte en termes de code supplémentaire. Je voudrais suggerer:
fun getTime(): Triple<Int, Int, Int> {
...
return Triple( hour, minute, second)
}
et l'utiliser avec déconstruction:
var (a, b, c) = getTime()
Si vous avez besoin de 4 ou 5 valeurs de retour (vous ne pouvez pas déconstruire plus de 5), allez avec Array
:
fun getTime(): Array<Int> {
...
return arrayOf( hour, minute, second, milisec)
}
et
var (a, b, c, d) = getTime()
P.S .: vous pouvez utiliser moins de variables qu'il n'y a de valeurs lors de la déconstruction, comme var (a, b) = getTime()
, mais vous ne pouvez pas utiliser plus ou vous obtiendrez un ArrayIndexOutOfBoundsException
Tandis qu'en général, une fonction ne peut renvoyer qu’une seule valeur, en Kotlin, en exploitant les avantages du type Pair et des déclarations de déstructuration, nous pouvons renvoyer deux variables d’une fonction. Prenons l'exemple suivant:
fun getUser():Pair<Int,String> {//(1)
return Pair(1,"Rivu")
}
fun main(args: Array<String>) {
val (userID,userName) = getUser()//(2)
println("User ID: $userID t User Name: $userName")
}
De: Livre de Kotlin fonctionnel
Selon la documentation de Kotlin ( https://kotlinlang.org/docs/reference/multi-declarations.html#example-returning-two-values-from-a-function ) vous pouvez le réaliser comme cette:
data class TimeData(val hour: Int, val minute: Int, val second: Int)
fun getTime(): TimeData {
// do your calculations
return TimeData(hour, minute, second)
}
// Get the time.
val (hour, minute, second) = getTime()
vous pouvez retourner plusieurs valeurs comme indiqué ci-dessous
data class Result(val result: Int, val status: Status)
fun function(...): Result {
// computations
return Result(result, status)
}
// Now, to use this function:
val (result, status) = function(...)
voir ceci documentation
pour plus d'exemple voir ceci lien
Il n'y a pas de tuple à Kotlin. Alternativement, vous pouvez utiliser classe de données avec déclaration de déstructuration .
data class Time(val hour: Int, val minute: Int, val second: Int)
func getTime(): Time {
...
return Time(hour, minute, second)
}
//Usage
val time = getTime()
println("${time.hour}:${time.minute}:${time.second}")
//Or
val (hour, minute, second) = getTime()
println("${hour}:${minute}:${second}")
Si vous ne souhaitez pas créer de classe de données pour chaque cas spécifique, vous pouvez créer des classes de données génériques et utiliser typealias
pour plus de clarté.
data class Two<A, B>(val a: A, val b: B)
data class Three<A, B, C>(val a: A, val b: B, val c: C)
data class Four<A, B, C, D>(val a: A, val b: B, val c: C, val d: D)
...
typealias Time = Three<Int, Int, Int>
Mais, à l’évidence, l’inconvénient est que vous devez utiliser la déclaration de déstructuration afin de lui attribuer un nom de propriété approprié.
val time = getTime()
println("${time.a}:${time.b}:${time.c}")
val (hour, minute, second) = getTime() //destructuring declaration
println("${hour}:${minute}:${second}")