Zastanawiam się, czy mogę napisać coś takiego w moim kodu:Czy możesz określić argument type dla None lub powiedzieć kompilatorowi, że jest to Option [String]?
None[String]
Zastanawiam się, czy mogę napisać coś takiego w moim kodu:Czy możesz określić argument type dla None lub powiedzieć kompilatorowi, że jest to Option [String]?
None[String]
Jeśli chcesz określić typ Option
możesz użyć:
Brak: Opcja [łańcuch]
Okrężnica jest adnotacją typu jawnego.
Można z scalaz:
import scalaz._
import Scalaz._
none[String] // res0: Option[String] = None
Option
jest rodzajem parametryzowane i jest zdefiniowany jako takie:
... sealed abstract class Option[+A] ...
to jest przedłużany o 2 innych klasach:
final case class Some[+A](x: A) extends Option[A]
i
case object None extends Option[Nothing]
Podczas gdy Some
może przyjmować dowolny typ argumentu, None
jest specjalną instancją/pojedynczą jednostką Option
sparametryzowaną za pomocą Nothing
. Ponadto Option
jest kowariantny w swoim argumencie typu [+A]
, co oznacza, że Option[Nothing]
może być używany wszędzie tam, gdzie oczekuje się, że Option
z jakimkolwiek innym typem argumentu, ponieważ Nothing
rozszerza wszystkie typy w Scali. Dlatego nie ma potrzeby tworzenia żadnych innych wartości reprezentujących wartość Nothing
, singleton None
będzie wystarczający dla wszystkich przypadków.
Pod względem rozciągliwości Option
to zamknięta klasa abstrakcyjna, więc nie można jej rozszerzyć. Nie można rozszerzyć jego podklas Some
i None
, ponieważ są one klasami przypadków.
Zazwyczaj nie trzeba nawet pisać coś w stylu None[String]
, ponieważ bardziej konkretny typ Option
jest zdefiniowany gdzieś w kontekście. Na przykład, jako argument funkcji:
def f(o: Option[String]) = ...; f(None)
lub jako wyrafinowania:
val o: Option[String] = None
Co więcej, to naprawdę nie obchodzi, co wpisać opcją było, czy jest to wartość Nothing
, nie można i tak coś z niego wyjdzie, jest jak null
w Javie, ale z zachowaniem Monadic.
Zostało wspomniane, że można zrobić coś podobnego w skalażu: none[String]
. Jest to po prostu cukier składniowy, aczkolwiek bardzo wygodny, aby zmniejszyć szczegółowość w niektórych przypadkach, gdy typy muszą być opisywane.Jest zdefiniowany jako takie:
final def none[A]: Option[A] = None
Dzięki za to, co napiszesz – jinglining
@Aleksey Izmailov: Twoja metoda "none" już istnieje w standardowej bibliotece: 'Opcja .empty'. –
to nie moja metoda, skopiowałem 'none' from scalaz;) –
Dziwię się, że nikt nie wspomniał o istnieniu Option.empty
:
scala> Option.empty[String]
res0: Option[String] = None
pamiętać, że w wielu przypadkach po prostu używając None
gdzie oczekiwany jest Option[String]
będzie działać dobrze. Lub innymi słowy, (jak to pokazano Aleksey Izmailov) dodaje się corrrect:
def f(o: Option[String]) = ...; f(None)
To dlatego None
rozciąga Option[Nothing]
, więc ze względu na Option
będącego covariant (i Nothing
jest podtypem z co inny typ), None
jest zawsze zgodny z Option[T]
dla każdego T
.
Dlatego również typ przypisanie jest również w porządku alternatywa (dla przypadków, w których trzeba zrobić, aby być jawne od rodzaju opcji, przez przykład, jeśli jest to potrzebne do jazdy typu wnioskowanie):
scala> None: Option[String]
res0: Option[String] = None
+1 dla "pustego" - nie tak bardzo różni się od skalazu –
Tak "Opcja.empty [Typ]' jest najlepszą praktyką. Podobnie dla pustych list i taki powinien zrobić 'List.empty [Type]' – samthebest
@samthebest Czy istnieją powody, dla których 'Option.empty' jest lepsze niż adnotacja typu explicit? Po prostu ciekawy – acjay
Wiem, że piszesz, chodzi o to, czy mogę określić typ jako None Like: val a: None [String] = – jinglining