web-dev-qa-db-fra.com

Comment passer un argument Tuple de la meilleure façon?

Comment passer un argument Tuple de la meilleure façon?

Exemple:

def foo(...): (Int, Int) = ...

def bar(a: Int, b: Int) = ...

Maintenant, je voudrais passer la sortie de foo à bar. Cela peut être réalisé avec:

val fooResult = foo(...)
bar(fooResult._1, fooResult._2)

Cette approche semble un peu moche, surtout quand nous traitons un n - Tuple avec n > 2. Nous devons également stocker le résultat de foo dans une valeur supplémentaire, car sinon foo doit être exécuté plus d'une fois en utilisant bar(foo._1, foo._2).

Y a-t-il un meilleur moyen de passer par le Tuple comme argument?

35
John Threepwood

Il existe une méthode spéciale tupled disponible pour chaque fonction:

val bar2 = (bar _).tupled  // or Function.tupled(bar _)

bar2 prend un tuple de (Int, Int) (identique aux arguments bar). Vous pouvez maintenant dire:

bar2(foo())

Si vos méthodes étaient en fait des fonctions (notez le mot clé val) la syntaxe est beaucoup plus agréable:

val bar = (a: Int, b: Int) => //...
bar.tupled(foo())

Voir également

52
Tomasz Nurkiewicz

L'utilisation de tupled, comme le mentionne @Tomasz, est une bonne approche.

Vous pouvez également extraire le tuple renvoyé de foo pendant l'affectation:

val (x, y) = foo(5)
bar(x, y)

Cela a l'avantage d'un code plus propre (pas de _1 et _2) et vous permet d'attribuer des noms descriptifs pour x et y, ce qui facilite la lecture de votre code.

9
dhg

Il vaut également la peine de connaître

foo(...) match { case (a,b) => bar(a,b) }

comme alternative qui ne vous oblige pas à créer explicitement un fooResult temporaire. C'est un bon compromis lorsque la vitesse et le manque d'encombrement sont tous deux importants. Vous pouvez créer une fonction avec bar _ puis le convertir pour prendre un seul argument Tuple avec .tupled, mais cela crée deux nouveaux objets de fonction à chaque fois que vous appelez la paire; vous pourriez stocker le résultat, mais cela pourrait encombrer votre code inutilement.

Pour une utilisation quotidienne (c'est-à-dire que ce n'est pas la partie limitant les performances de votre code), vous pouvez simplement

(bar _).tupled(foo(...))

en ligne. Bien sûr, vous créez deux objets de fonction supplémentaires, mais vous venez probablement de créer également le tuple, donc vous ne vous souciez pas de que beaucoup, non?

9
Rex Kerr