une conversion implicite pourrait / devrait de T à l'option [T] ajouter / créé à Scala?

StackOverflow https://stackoverflow.com/questions/1746359

  •  20-09-2019
  •  | 
  •  

Question

Est-ce l'occasion de faire les choses un peu plus efficace (pour le prorammer): Je trouve ça devient un peu fatiguant d'avoir à envelopper les choses dans Some, par exemple Some(5). Qu'en est-il quelque chose comme ceci:

implicit def T2OptionT( x : T) : Option[T] = if ( x == null ) None else Some(x)
Était-ce utile?

La solution

Vous perdriez une certaine sécurité de type et peut-être une source de confusion. Par exemple:

  val iThinkThisIsAList = 2 
  for (i <- iThinkThisIsAList) yield { i + 1 }

I (pour une raison quelconque) pensais avoir une liste, et il n'a pas détecté par le compilateur quand j'itéré parce qu'il a été converti automatiquement à une option [Int].

Je dois ajouter que je pense que cela est un grand implicite d'avoir explicitement importé, tout probablement pas un défaut global.

Autres conseils

Notez que vous pouvez utiliser le modèle explicite implicite qui éviterait la confusion et conserver le code laconique en même temps.

Qu'est-ce que je veux dire par implicite explicite est plutôt que d'avoir une conversion directe de T à Option[T] vous pourriez avoir une conversion à un objet wrapper qui fournit les moyens de faire la conversion de T à Option[T].

class Optionable[T <: AnyRef](value: T) {
  def toOption: Option[T] = if ( value == null ) None else Some(value)
}

implicit def anyRefToOptionable[T <: AnyRef](value: T) = new Optionable(value)

... je pourrais trouver un meilleur nom pour cela que Optionable, mais vous pouvez maintenant écrire du code comme:

val x: String = "foo"
x.toOption // Some("foo")

val y: String = null
x.toOption // None

Je crois que cette façon est totalement transparente et contribue à la compréhension du code écrit -. Éliminant tous les chèques pour nul d'une manière agréable

Notez la T <: AnyRef -. Vous devriez faire cette conversion implicite pour les types qui permettent aux valeurs de null, qui par définition sont des types de référence

Les lignes directrices générales pour les conversions implicites sont les suivantes:

  • Lorsque vous avez besoin d'ajouter des membres à un type (à la « classes ouvertes », alias le modèle « Pimp ma bibliothèque »), convertir en nouveau type qui s'étend AnyRef et qui ne définit que les les membres dont vous avez besoin.
  • Lorsque vous avez besoin de « corriger » une hiérarchie d'héritage. Ainsi, vous avez une A de type qui devrait avoir sous-classé B, mais n'a pas pour une raison quelconque. Dans ce cas, vous pouvez définir une conversion implicite de A à B.

Ce sont les uniquement les cas où il convient de définir une conversion implicite. Toute autre conversion se heurte à des problèmes de type sécurité et l'exactitude pressé.

Il ne fait pas vraiment de sens pour T d'étendre Option[T], et, évidemment, le but de la conversion est non seulement l'ajout de membres. Ainsi, une telle conversion serait inopportune.

Il semblerait que cela pourrait être source de confusion avec d'autres développeurs, car ils lisent votre code.

En général, il semble, implicit travaille pour aider cast d'un objet à un autre, pour découper le code de coulée confusion qui peut coder le désordre, mais, si j'ai une variable et il devient un Some alors cela semble en quelque sorte à être gênant .

Vous pouvez mettre un peu de code montrant utilisé, pour voir comment il serait source de confusion.

Vous pouvez également essayer de surcharger la méthode:

def having(key:String) = having(key, None)

def having(key:String, default:String) = having(key, Some(default))

def having(key: String, default: Option[String]=Option.empty) : Create = {
  keys += ( (key, default) )
  this
}

Cela ressemble bien à moi, si cela ne fonctionne pas pour un T primitif (qui ne peut être nulle). Je suppose que les primitives génériques obtient toujours boxed non spécialisés, donc sans doute il est très bien.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top