scala: Map.orElseThrow()

0

Jak nie znajdzie klucza w mapie to niech wyrzuca wyjątek.

val onError: Unit = {
    logger.error("Not found iso code for country name: " + countryName)
    throw new Exception
}

isoCountryIsoCodeMap.get("argentina") match {
    case Some(s) => Some(s)
    case _ => onError
})

w powyższym ZAWSZE odpala mi onError

1

Jeśli bardzo chcesz rzucać wyjątek to po prostu zrób isoCountryIsoCodeMap("argentina"). Jak nie znajdzie klucza to rzuci NoSuchElementException. Nie mniej, zwróć uwagę na to, że API kolekcji w Scali nie bez powodu nie oferuje takich metod jak getOrElseThrow. Jeśli masz przypadek gdzie klucza może nie być to użyj .get i zostań z Optionem aż do momentu w którym możesz coś z nim zrobić. Staraj się nie rzucać wyjątków

0
DisQ napisał(a):

Jeśli bardzo chcesz rzucać wyjątek to po prostu zrób isoCountryIsoCodeMap("argentina"). Jak nie znajdzie klucza to rzuci NoSuchElementException.

To by było OK gdyby rzucał którego elementu nie znalazł.

0
  1. Twój link do SO prowadzi do pytania i odpowiedzi o Javowych Optionalach. Jak to się niby ma do Scali?
  2. Wypisz zawartość tablicy żeby się upewnić co w niej jest.
  3. To by było OK gdyby rzucał którego elementu nie znalazł. - przecież rzuca.
0
Julian_ napisał(a):
DisQ napisał(a):

Jeśli bardzo chcesz rzucać wyjątek to po prostu zrób isoCountryIsoCodeMap("argentina"). Jak nie znajdzie klucza to rzuci NoSuchElementException.

To by było OK gdyby rzucał którego elementu nie znalazł.

Możesz do tego podejść albo poprzez rzucanie wyjątków, albo poprzez stworzenie struktur, które będą odpowiednio reprezentowały to co chcesz uzyskać (oczywiście pod warunkiem, że ten optional jest nie do przyjęcia), pi razy drzwi:

sealed trait IsoCodeRetrievalStatus extends Product with Serializable
final case class IsoCodeRetrieved(isoCode: String) extends IsoCodeRetrievalStatus
final case class IsoCodeMissing(isoCountry: String) extends IsoCodeRetrievalStatus

val x: IsoCodeRetrievalStatus = isoCountryIsoCodeMap.get("argentina").fold[IsoCodeRetrievalStatus](IsoCodeMissing("argentina")(isoCode => IsoCodeRetrieved(isoCode))

Wtedy, jak już będziesz musiał się dowiedzieć czy się udało czy nie to możesz zrobić pattern matching:

x match {
    case IsoCodeRetrieved(isoCode) => ???
    case IsoCodeMissing(isoCountry) =>
        log.error("Missing ISO code for country: {}", isoCountry)
        ???
}
3

Aaaa dobra, już widzę o co biega.

val onError: Unit = {
    logger.error("Not found iso code for country name: " + countryName)
    throw new Exception
}

Powyższe to zwykła (zachłanna) zmienna, a więc zostanie zawsze wykonana. Jak chcesz mieć metodę to zrób def:

def onError: Unit = {
    logger.error("Not found iso code for country name: " + countryName)
    throw new Exception
}
0

Prościej będzie tak:

def getOr(key: A, onError: A => Unit): B {
    val value = map.get(key)
    value.getOrElse(onError(key))
    value
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1