2016-07-18 2 views
0

元々私は次のようなことがありました。スカラをリファクタリングして検索関数を引数として使用すると、Option [Any]が発行されます

private def getCurrentField[A](newState: Asset, currentState: Option[Asset], searchFunction: Asset => Option[A]) : Option[A] = 
    newState.content.flatMap(_.contract.flatMap(_.childSource)) orElse { 
     currentState match { 
     case Some(state) => searchFunction(state) 
     case None => None 
     } 
    } 

    val getCollection : Asset => Option[Collection] = (state : Asset) => state.assetGroup.flatMap(_.collection) 
    val getChildSource : Asset => Option[String] = (state : Asset) => state.content.flatMap(_.contract.flatMap(_.childSource)) 

...しかし、これは私のコンパイラエラーを与える:

私は次のようにそれを単純化し、いくつかの作業の後にそう
private def getCollection(newState: Asset, currentState: Option[Asset]) = 
    newState.assetGroup.flatMap(_.collection) match { 
     case Some(collection) => Some(collection) 
     case None => currentState match { 
     case Some(state) => state.assetGroup.flatMap(_.collection) 
     case None => None 
     } 
    } 

    private def getChildSource(newState: Asset, currentState: Option[Asset]) = 
    newState.content.flatMap(_.contract.flatMap(_.childSource)) match { 
     case Some(childSource) => Some(childSource) 
     case None => currentState match { 
     case Some(state) => state.content.flatMap(_.contract.flatMap(_.childSource)) 
     case None => None 
     } 
    } 

    private def getParentSource(newState: Asset, currentState: Option[Asset]) = 
    newState.content.flatMap(_.contract.flatMap(_.parentSourceId)) match { 
     case Some(childSource) => Some(childSource) 
     case None => currentState match { 
     case Some(state) => state.content.flatMap(_.contract.flatMap(_.parentSourceId)) 
     case None => None 
     } 
    } 

:それはボイラープレートの多くが含まれてい

[warn] <filename_removed>.scala:68: a type was inferred to be `Any`; this may indicate a programming error. 
[warn]  currentState match { 
[warn]     ^
[error] _:67: type mismatch; 
[error] found : Option[Any] 
[error] required: Option[A] 
[error]  newState.content.flatMap(_.contract.flatMap(_.childSource)) orElse { 
[error]                ^
[warn] one warning found 
[error] one error found 

戻り値の型をgetCurrentFieldにすると、コンパイルされテストに合格しますが、コンパイラの警告:a type was inferred to be Anyが表示されます。

この場合、タイプパラメータを処理するにはどうすればよいでしょうか?

+1

スカラでリファクタリングを行う場合は、必ず開始型コードに戻り型の注釈を追加することをお勧めします。 – Daenyth

答えて

0

_.childSourceOption[Asset]であり、searchFucntionOption[A]です。したがって、_.contract_.childSourceの両方が定義されている場合(.flatMapSome)、返されるのはOption[Asset]で、それ以外の場合(.orElse)は返されるタイプがOption[A]です。

Anyは限りコンパイラが知ることができるよう、AssetAの唯一の共通のスーパークラスですので、だから、あなたの関数の結果の戻り値の型は、Option[Any]なければなりません。

0

リファクタリングされたバージョンでは、検索機能の1つを置き換えましたが、もう1つは置き換えられませんでした。以下は、警告を取り除き、正しくコンパイルしてテストします:

private def getCurrentField[A](newState: Asset, currentState: Option[Asset], searchFunction: Asset => Option[A]) : Option[A] = 
searchFunction(newState) orElse { 
    currentState map searchFunction getOrElse None 
} 
関連する問題