5
votes

Impossible de masquer la classe Scala de l'importation

A écrit ce code

scala> import scala.collection.immutable.{Stream => DoNotUse}
import scala.collection.immutable.{Stream=>DoNotUse}

scala> Stream(1, 2, 3)
res1: scala.collection.immutable.Stream[Int] = Stream(1, ?)

Mais la deuxième ligne ne devrait-elle pas échouer? parce que j'ai caché la classe Stream de l'importation à la ligne 1? pourquoi est-il encore visible?

J'ai aussi essayé

scala> import scala.collection.immutable.{Stream => _}
scala> Stream(1, 2, 3)
res0: scala.collection.immutable.Stream[Int] = Stream(1, ?)

Encore une fois, cela est toujours visible.


7 commentaires

Vous ne pouvez pas le désimporter via scala.collection.immutable , car il est intégré en tant qu'alias de type directement au niveau supérieur scala package. Qu'essayez-vous de réaliser exactement?


Je veux par défaut fs2.Stream. Je ne veux jamais voir scala.collection.immutable.Stream.


Je pense que si vous importez simplement fs2.Stream , cela masquera celui par défaut


uniquement si l'importation fs2.Stream est la dernière. De plus, il devrait toujours être possible de masquer l'implémentation par défaut de Stream.


Eh bien, en théorie, il y a -Yno-importations < / code> ... Mais je suis presque sûr que cela ne vaut pas la peine pour ces quatre caractères ( fs2. ).


Stream est obsolète dans la version 2.13. Il serait pratique d'avoir une option pour que les importations root n'importent jamais des éléments obsolètes. Je vais créer un ticket!


J'ai créé ce ticket, apparemment, et quelqu'un d'autre avait déjà créé un ticket pour cette question sur github. com / scala / bug / issues / 11317


3 Réponses :


-1
votes

Vous ne pouvez pas "désimporter" une valeur importée. Si vous écrivez import scala.collection.immutable. {Stream => _} , vous ajouterez simplement une autre importation à votre espace de noms.


Voici un autre exemple:

import foo.Stream
val x: Stream[_] = ??? // this variable has type `foo.Stream`

// Here we have another import of a class with the same name.
// This shadows the first import, so any occurence of `Stream`
// does from now on refer to `bar.Stream`.
import bar.Stream
val x: Stream[_] = ??? // This variable has type `bar.Stream`

La deuxième ligne ne supprime pas la première importation. Les deux lignes ajoutent simplement une importation supplémentaire à votre espace de noms. Vous pouvez maintenant faire référence à Stream comme Foo et Bar .


Pourquoi ne voulez-vous pas supprimer une importation? Si vous ne souhaitez pas utiliser la classe, ne l'utilisez pas. Il n'est pas nécessaire de supprimer une importation. Cela n'ajoute pas de dépendance sur Stream ou tout autre inconvénient au moment de l'exécution, les importations sont un concept uniquement à la compilation.

Peut-être que vous avez votre propre classe nommée Stream code > que vous souhaitez utiliser. Il n'est donc pas nécessaire de "supprimer" l'importation par défaut du Stream . Importez simplement votre classe. Cela masquera l'importation par défaut.

import scala.collection.immutable.{Stream => Foo}
import scala.collection.immutable.{Stream => Bar}


1 commentaires

La raison de la suppression de l'alias standard de la portée est d'éviter une utilisation accidentelle et d'améliorer l'auto-complétion dans l'outillage. Une utilisation accidentelle peut être subtile d'une manière que vous pourriez ne pas remarquer, par exemple, un Set de remplacement par une signature contient plus stricte.



2
votes

Voici un exemple avec les nouveaux -Yimports de la version 2.13.

scala> :pa
// Entering paste mode (ctrl-D to finish)

package mystuff {
  class C { def f = new Stream[Int] }
}

// Exiting paste mode, now interpreting.


scala> new mystuff.C().f
res1: mystream.Stream[Int] = mystream.Stream@715fa8c5

Les importations plus tard dans la liste occultent les plus anciennes:

package object mystuff {
  type Stream[A] = mystream.Stream[A]
}


0 commentaires

0
votes

Dans Scala, vous pouvez utiliser certains types par défaut sans importation. Tous ces types se trouvent dans le package scala._ . Par exemple Liste , Throwable etc.

scala.collection.immutable.Stream a un alias dans ce package: https://github.com/scala/scala/blob/2.13.x/src/library/scala/package.scala#L86


1 commentaires

OK, alors comment cela répond-il à la question? Si vous essayez de dire que immutable.Stream ne peut pas être bloqué, et qu'il est impossible de garantir aucune utilisation accidentelle, dites-le.