web-dev-qa-db-fra.com

Comment pouvons-nous renvoyer plusieurs valeurs d'une fonction dans Kotlin, comme nous le faisons dans swift?

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.

32
AwaisMajeed

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()
65
zsmb13

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

2
Ekeko

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

2
Mahabub Karim

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()
1
Markus Penguin

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

0
Shruti

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}")
0
BakaWaii