2016-11-30 26 views
1

私はKotlin KBuildersを使用していますが、いくつかのprotobuffsがあり、私を混乱させる状況に陥っています。関数ビルダーとの型推論

まず、ファイル名とシリアライズされたJSONのリストを取得し、そのJSONをプロトタイプにデシリアライズする関数があります。

fun parseFileData(fileName: String, lines: List<String>): Data.Builder.() -> Unit = when (fileName) { 
     SOME_FILE_NAME -> deserializeLinesToModel(lines, DataModel::class.java) 
       .let { 
        return { 
         dataMeasurement = buildDataMeasurement { 
          property1 = it.reduce { acc, n -> acc + n } 
          measurementMsec = it.map { it.measurementMsec } 
         } 
        } 
       } 
     else -> throw UnsupportedOperationException() 

私が理解できなかった最初のことは、なぜletブロック内での復帰が必要なのかということでした。しかし、それは私が上に移動したので働いた。

私は後でコードを他の場所に簡単にするためにいくつかのものをリファクタリングすることを決定し、このようなものになってしまった:

fun parseFileData(fileName: String, factory: DataFactory): Sequence<Data.Builder.() -> Unit> = when (fileName) { 
     SOME_FILE_NAME -> factory.getSomeFileSequence() // returns Sequence<Model> 
           .batch(1000) // process data in batches of 1000 to reduce memory footprint and payload size 
           .map { return { 
              dataMeasurement = buildDataMeasurement { 
              property1 = it.reduce { acc, n -> acc + n } 
              measurementMsec = it.map { it.measurementMsec } 
            } 
           } 
     else -> throw UnsupportedOperationException() 

だから、基本的には、代わりにプロセスの各バッチをリストとして、私は工場からシーケンスを読み込みますそれを一連のリストにバッチし、各リストをData.Builder.() -> Unitにマップしようとします。しかし、今度はreturn is not allowed hereになります。私はリターンの有無にかかわらず、複数のバリエーションを試してみました。私が得た最も近いのは、型推論に失敗するシーケンス<() - > Unit>の戻り型です。

誰でもここで何が起こっているのか説明できますか?なぜこのタイプは推論できないのですか?

+0

あなたはhttps://kotlinlang.org/docs/reference/lambdas.htmlを読んでいますか? 2番目のケースでは、マップブロック(lambda)の最新式は戻り値です。最初のケースでは、 "非ローカルリターン"と呼ばれています。https://kotlinlang.org/docs/reference/inline-functions.html#non-local-returns – IRus

+0

すべてのタイプを指定せずにコードをリファクタリングすることはできません。機能。コードベースへのリンクを公開するのはどうですか? – voddan

+0

残念ながら、私はコードベースを共有できません。私は時間があるときに自己完結型のクラスに関連するコードを書くようにします。 –

答えて

2

returnmapラムダは非ローカルリターンです。最も近いfun関数から復帰しようとしますが、その場合はparseFileDataになります。

非ローカルリターンは、ラムダパラメータがコールサイトでインライン化されたインライン関数からのみ許可され、Sequencemap拡張子はインライン関数ではありません。

ラムダ自体から値を返す場合は、qualified return[email protected] ...を使用するか、完全に省略します。ブロックの最後の式が結果として返されます。