我有以下幾點case class:
case class Example[T](
obj: Option[T] | T = None,
)
這允許我像Example(myObject)而不是Example(Some(myObject)).
要使用 obj,我需要將其規范化為Option[T]:
lazy val maybeIn = obj match
case o: Option[T] => o
case o: T => Some(o)
the type test for Option[T] cannot be checked at runtime
我試過了,TypeTest但我也收到了警告 - 或者我發現的解決方案看起來很復雜 - 請參閱https://stackoverflow.com/a/69608091/2750966
有沒有更好的方法在Scala 3 中實作這種模式?
uj5u.com熱心網友回復:
我不知道 Scala3。但你可以簡單地這樣做:
case class Example[T](v: Option[T] = None)
object Example {
def apply[T](t: T): Example[T] = Example(Some(t))
}
uj5u.com熱心網友回復:
為此,我們有一個專門的Option-like 型別:(OptArg在 Scala 2 中,但應該很容易移植到 3)
import com.avsystem.commons._
def gimmeLotsOfParams(
intParam: OptArg[Int] = OptArg.Empty,
strParam: OptArg[String] = OptArg.Empty
): Unit = ???
gimmeLotsOfParams(42)
gimmeLotsOfParams(strParam = "foo")
它依賴于隱式轉換,因此您必須小心使用它,即不要將其用作Option.
的實作OptArg非常簡單,如果您不想要外部依賴項,那么您可以將它復制到您的專案或某種“公共”庫中。
uj5u.com熱心網友回復:
編輯:以下答案不正確。從 Scala 3.1 開始,流分析只能檢查可空性。Scala 書籍中提供了更多資訊。
我認為已經給出的答案可能更適合您提出的用例(公開 API 可以采用一個簡單的值并將其規范化為Option)。
然而,標題中的問題仍然很有趣,我認為解決它是有道理的。
您所觀察到的是型別引數在運行時被擦除的結果,即它們僅在編譯期間存在,而匹配發生在運行時,一旦它們被擦除。
但是,Scala 編譯器能夠對聯合型別執行流分析。直覺上,我會說可能有一種方法可以讓它在模式匹配中作業(就像你所做的那樣),但你可以使用ifand isInstanceOf(不是那么干凈,我同意)確保它作業:
case class Example[T](
obj: Option[T] | T = None
) {
lazy val maybeIn =
if (obj.isInstanceOf[Option[_]]) {
obj
} else {
Some(obj)
}
}
您可以在 Scastie 上使用此代碼。
這是 2019 年在編譯器中添加流分析時的公告。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/358567.html
