4

メソッドを使用しようとしていますが、パラメーター化された正しいクラスのインスタンスの代わりに、etiherOption.getOrElse()が返されます。私はこの問題についての言及を見つけることができず、そこにあるべきではないようです。私は何が間違っているのですか?AnyScalaObjectOption

class MyClass {

  def isOk = true

}

val myVal = Some(new MyClass) // :Option[MyClass]

val check = myVal.getOrElse(false).isOk

isOkメソッドを呼び出そうとするため、メソッドを呼び出すことができませんAny

4

7 に答える 7

17

and ( )isOkの基本クラスでメソッドを呼び出そうとしています。MyClassBooleanAny

これを試して:

scala> class MyClass(b: Boolean) { def isOk = b }
defined class MyClass

scala> val myVal = Some(new MyClass(true))
myVal: Some[MyClass] = Some(MyClass@35d56bbe)

scala> myVal.map{_.isOk}.getOrElse(false)
res0: Boolean = true

scala> myVal.getOrElse(new MyClass(false)).isOk
res1: Boolean = true
于 2012-05-22T11:09:04.323 に答える
8

設計どおりに動作します。この式:

myVal.getOrElse(false)

MyClassラップされていないインスタンスまたは(Option実際にはNone)-のいずれかを返しますfalseMyClassとの唯一の一般的なタイプBooleanは...ですAny。そして、これはあなたが見ているものです。

これが機能するためには、MyClassfromと互換性のあるものを返す必要がありますgetOrElse()

myVal.getOrElse(new MyClass).isOk

または、 nullオブジェクトパターンを実装したい場合もあります。

object MyClass {
  val Empty = new MyClass
}

myVal.getOrElse(MyClass.Empty).isOk
于 2012-05-22T11:08:24.293 に答える
6

ブール値を使用してOption[MyClass]でgetOrElseを適用しているため、それらの一般的なスーパークラスはAnyです。

パターンマッチする必要があります:

val check = myVal match {
  case Some(c) => c.isOk
  case None => false
} 
于 2012-05-22T11:10:24.247 に答える
4

を呼び出しgetOrElseていOption[MyClass]ます。Booleanパラメータとしてをに渡しますgetOrElse。何が起こるかというと、Scalaはオプションをに変換しているということですOption[Any]。なぜならAny、はとの最も一般的なタイプだMyClassからBooleanです。

の代わりにMyClass(またはのサブクラスMyClass)をに渡します。getOrElsefalse

于 2012-05-22T11:08:34.507 に答える
1

getOrElseはfalseを返す可能性があるため、MyClassとfalseの一般的なタイプはAnyです。

于 2012-05-22T11:08:49.673 に答える
1

ジョニーエバーソンは正しいです。パターンマッチングがその答えです。この場合、彼の答えのパターンは次のようになります。exists

scala> Some(new MyClass) :: None :: Nil map(_.exists(_.isOK))
res12: List[Boolean] = List(true, false)
于 2012-05-22T14:57:45.897 に答える
1

したがって、、、Option[A]関数、およびオプション値がの場合のA => Bデフォルトがあり、最終的には。になります。(あなたの場合、isとis )。BNoneBAMyClassBBoolean

ハスケラーである私が最初にやろうと思うのはフーグルです。OptionHaskellでは、と呼ばれていることを思い出してくださいMaybe。だから私たちはフーグルMaybe a -> (a -> b) -> b -> bし、トップヒットはmaybe :: b -> (a -> b) -> Maybe a -> b、まさに私たちが望むことをします。

data MyClass = MyClass { isOK :: Bool }
newMyClass = MyClass { isOK = true }

myVal = newMyClass
check = maybe False isOK myVal

それはよくて良いことですが、Scalaはどうですか?さて、hoogleに相当するScalaはScalexです。Scalexで検索しましOption[A] => B => (A => B) => Bたが、役に立ちませんでした。代わりに、maybeHaskellで関数がどのように実装されたかを確認しましょう。hoogleから適切なリンクをたどると、ソースを見つけることができます。

maybe :: b -> (a -> b) -> Maybe a -> b
maybe n _ Nothing  = n
maybe _ f (Just x) = f x

Scalaに翻訳するのは簡単なようです

def option[A, B](opt: Option[A])(n: B)(f: A => B) = opt match {
  case None => n
  case Some(x) => f(x)
}

これは、次のように使用できます。

val check = option(myVal)(false)(_.isOK)

カリー化を減らしたり、Optionクラスをポン引きしたりする場合は、私よりもScalaの専門家に尋ねる必要がありますが、これは基本的にJhonnyEversonが提案したパターンマッチングに帰着することに注意してください。

于 2012-05-22T15:41:44.323 に答える