2014-07-17 12 views

Odpowiedz

7

Jeśli chcesz określić typ Option możesz użyć:

Brak: Opcja [łańcuch]

Okrężnica jest adnotacją typu jawnego.

1

Można z scalaz:

import scalaz._ 
import Scalaz._ 

none[String] // res0: Option[String] = None 
+0

Wiem, że piszesz, chodzi o to, czy mogę określić typ jako None Like: val a: None [String] = – jinglining

8

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 
+0

Dzięki za to, co napiszesz – jinglining

+0

@Aleksey Izmailov: Twoja metoda "none" już istnieje w standardowej bibliotece: 'Opcja .empty'. –

+0

to nie moja metoda, skopiowałem 'none' from scalaz;) –

26

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 
+0

+1 dla "pustego" - nie tak bardzo różni się od skalazu –

+0

Tak "Opcja.empty [Typ]' jest najlepszą praktyką. Podobnie dla pustych list i taki powinien zrobić 'List.empty [Type]' – samthebest

+0

@samthebest Czy istnieją powody, dla których 'Option.empty' jest lepsze niż adnotacja typu explicit? Po prostu ciekawy – acjay

Powiązane problemy