7
votes

Comment déclarer TUPLE comme type de retour d'une fonction et comment accéder à TUPLE dans le code de l'appelant à Scala?

Supposons que j'ai une fonction scala censée renvoyer un tuple de type (chaîne, int, int) mappé sur les touches (mots, rangées, col) code>: xxx pré>

dans le code de l'appelant: p> xxx Pré>

Le code est incomplet. Alors, comment puis-je déclarer et retourner le tuple dans la fonction et comment utiliserais-i que j'utiliserais dans le scénario ci-dessus? P>

est le type recommandé par Tuple dans la case ci-dessus, même si la carte semble mieux adaptée? P>

malgré Toutes les réponses que j'ai reçues, aucune réponse n'a abordé la question de savoir comment puis-je déclarer tuple et remplir le tuple plus tard dans le code (ne pas attribuer aux valeurs à tuple à la déclaration de temps comme cette réponse suggère: P>

var words, row, col  // how do I delcare tuple here?
    if(someValue) {

      getResults(someValue)  // assigns the tuple values to keys words, row and col
             // how I do that here ?
      // reference words, row and col variables here

    } else
      getResults(someOtherValue)  // assigns the tuple values to keys words, row and col
    // reference words, row and col variables here
    }


1 commentaires

Attribuez-vous des valeurs à mots , ligne et col plusieurs fois, écrasant ainsi leur contenu?


5 Réponses :


20
votes

L'assidation multiple peut être effectuée dans un Mode syntaxiquement simple ( qui repose sur les types de tuple ' non apply code>), comme suit: xxx pré>

Vous pouvez simplement modifier ce dernier exemple à: p> xxx Pre>

Le si code> L'instruction renvoie un (chaîne, int, int) code> et les composants correspondants seront attribués à mots code> , ligne code> et col code> dans la commande. p>

Si vous vous demandiez comment annoter votre déclaration de méthode avec le type de retour, c'est facile aussi: P>

def getResult(param: Int): (String, Int, Int) = {
   ...
}


6 commentaires

Cela semble être une solution propre répondant à la moitié de ma question, mais malheureusement dans mon cas dans le code réel, il y a beaucoup de blocage dans le cas de l'affectation des autres VARS déclarés à l'extérieur du bloc, etc., donc je ne pouvais donc pas utiliser votre approche.


Cela ressemble à votre blocage pourrait être refoulé - surtout à la lumière de cette tâche multiple assez simple, il est souvent préférable d'avoir des blocs comme celui-ci élaborer plusieurs variables (par exemple, hôte , port , chemin pour la configuration de la connexion HTTP) et renvoyez-les sous forme de tuple - en les attribuant aux variables requises immédiatement à l'extérieur du bloc.


@RJC, je pense que @ andrzej-doyle a répondu à votre question à la portée complète.


Quand j'ai ajouté mon commentaire à ce moment-là, la réponse avait moins d'informations qu'aujourd'hui.


@Andrzej: Vous avez oublié un signe égal dans la signature de méthode getresult .


@RJC: Vous devriez penser à refactoriser votre code. BTW beaucoup d'aller peut se produire dans le si sinon présenté par Andrzej ...



5
votes

Les tuples en tant que valeurs de retour sont utiles lorsque vous avez une fonction qui doit renvoyer plusieurs valeur et où ces valeurs n'ont pas besoin de rester ensemble en tant que structure (si elles ont besoin de rester ensemble, cela aurait plus de sens à Définissez une classe de cas simple).

Pour déclarer une fonction avec un 3 tuple en tant que type de retour et renvoyer un 3 tuple, vous ferez: xxx

ceci est en réalité du sucre syntaxique pour: xxx

scala a des classes tuplen pour N: 1 à 22


0 commentaires

1
votes

Les tuples sont ok mais vous pouvez également envisager la classe de cas: xxx

Il est immuable et a beaucoup de fonctionnalités utiles. Je préfère la classe de cas sur les tuples, car les champs ont des noms utiles. En savoir plus ici: http://www.codecommit.com/blog/ scala / classes de cas-sont-cool


0 commentaires

6
votes

Tout d'abord, vous devez décider si vous avez besoin d'une carte.

Vous voudrez peut-être une carte car p>

  1. Vous obtenez différentes paires de la valeur de clé à chaque fois li>
  2. Vous avez gênant de nombreuses paires de clés et avez besoin de les introduire sur eux pour les gérer li>
  3. Vous avez des valeurs essentielles comme Data ​​em>, pas seulement dans le cadre de votre code et que vous devez extraire la valeur correspondante li> OL>

    Jusqu'à présent, cela ne ressemble à aucune de ces trois choses sont le cas. Donc, vous n'avez pas vraiment besoin de map em>, vous avez juste besoin d'un nom em> pour vos différents types de données. (C'est-à-dire que vous pouvez laisser le compilateur gérer le mappage entre votre nom et les données correspondantes.) P>

    La manière la plus directe d'obtenir des valeurs nommées est avec une classe de cas: P>

    println(getResult._3)   // Prints 10
    


0 commentaires

2
votes

AM I DROITEZ QUE VOUS ASSUMÉ Vous souhaitez déclarer vos variables de résultat (et devez-la y accéder en dehors de la construction if / else), puis appelle le code qui les définit et les utilise (à l'intérieur de la construction if / autre)? Si tel est le cas, il devrait être aussi simple que

var words: String = _
var row: Int = _
var col: Int = _
...
if (someValue) {
  val (words, row, col) = getResults(someValue)
  // use words, row, col
  // Note: keyword 'val' added per comments by Prometheus and John Threepwood below
} else {
  val (words, row, col) = getResults(someOtherValue)
  // use words, row, col
  // Note: keyword 'val' added per comments by Prometheus and John Threepwood below
}


4 commentaires

Cette solution jette une erreur avec SCANA 2.9.1 lors de la tentative de ré-attribution des mots mots , ligne et col dans la ligne (mots, rangée, col) = getResults (...) .


Même pour moi, on dirait que pour une raison quelconque, ce n'est plus valide.


Comme indiqué par @JohnTreepwood, à Scala 2.13.5, la syntaxe correcte est Val (mots, rangée, col) = getResults (quelqueévalue)


Merci@prometheus - avez-vous mis à jour ma réponse en conséquence.