Kuにおけるスコープ関数
Kotlinは、オブジェクトの文脈の中からコードのブロックを実行するのを許しますscope functions . 小林は5人を定義する.
私たちは、実装、可能なユースケース、および実際のライブラリについては後で話します.第1に、我々はコリンが輝く場所とダーツが失敗するところを調査する必要があります.
からofficial documentation , 高次関数は、1つまたは複数の関数をパラメーターとして受け取り、関数を返す関数です.kotlinの高次関数は,関数リテラルのアイデアを受信機でサポートする.例えば、型
この動作は、拡張機能内の受信オブジェクトのメンバーにアクセスできるように拡張機能に似ています.
さあ、見ましょう
実際には、このように使用することができます.
フードの下で、拡張機能は静的に解決されます.そして、それらが拡張しているクラスとの接続を持たない通常の静的メソッドであるということです.コンパイラは拡張機能を生成します.
ダートはこの動作を提供しません.
それで、あなたは尋ねるかもしれません、プロトタイプまたはプロトタイプの継承で働くことは可能ですか?このようにして、クラスのシグネチャを変更し、JavaScript開発者と同じようなものに頼ります
答えは、もう一度、負です.ダートはこの動作を提供しません.プロトタイプ/プロトタイプチェーンではなく、継承に依存します.
これらの2つの制限が我々に反対して、残りだけが反射です.DARTのサポートを介して反射
方法の制限についての議論で、最初に実装を議論しましょう.
小林で
つの異なる米国のケースがあります コールチェーンの結果に1つ以上の関数を呼び出す 非NULL値だけでコードブロックを実行する コードの読みやすさを改善するための限られた範囲でローカル変数を導入する
非拡大
ライブラリへのソースコードはGithubアカウントで利用可能です.現時点では利用できません
let
, run
, with
, apply
and also
. 残念なことに、DARTプログラミング言語の制限のために、それらのうちの3つだけが実行されることができます:let
, run
(非拡張メソッドとして)also
.私たちは、実装、可能なユースケース、および実際のライブラリについては後で話します.第1に、我々はコリンが輝く場所とダーツが失敗するところを調査する必要があります.
コルト要塞対ダート制限
からofficial documentation , 高次関数は、1つまたは複数の関数をパラメーターとして受け取り、関数を返す関数です.kotlinの高次関数は,関数リテラルのアイデアを受信機でサポートする.例えば、型
A.(B) -> C
受信オブジェクトで呼び出すことができる任意の関数を表しますA
型のパラメータB
, 返り値C
.この動作は、拡張機能内の受信オブジェクトのメンバーにアクセスできるように拡張機能に似ています.
さあ、見ましょう
apply
, スコープ関数の一つ:inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
こちらです.block
パラメータはレシーバとの関数リテラルです.コードを読んで、kotlinの創意工夫を観察しましょうT
, パラメータを受け入れず、何も返さない任意のメソッドを定義することができますT
.実際には、このように使用することができます.
data class User(
val username: String,
var email: String = "",
var age: Int = -1
)
fun main() {
val user = User(username = "john_doe")
user.apply {
email = "[email protected]"
age = 25
}
}
この例では、メールオブジェクトと年齢割り当てをユーザーオブジェクトに適用します.なしでapply
, 手動で割り当てを処理する必要がありますval user = User(username = "john_doe")
user.email = "[email protected]"
user.age = 25
ダートの話
フードの下で、拡張機能は静的に解決されます.そして、それらが拡張しているクラスとの接続を持たない通常の静的メソッドであるということです.コンパイラは拡張機能を生成します.
ダートはこの動作を提供しません.
それで、あなたは尋ねるかもしれません、プロトタイプまたはプロトタイプの継承で働くことは可能ですか?このようにして、クラスのシグネチャを変更し、JavaScript開発者と同じようなものに頼ります
Function.prototype.call
?答えは、もう一度、負です.ダートはこの動作を提供しません.プロトタイプ/プロトタイプチェーンではなく、継承に依存します.
これらの2つの制限が我々に反対して、残りだけが反射です.DARTのサポートを介して反射
dart:mirrors
パッケージ(標準ライブラリの一部)、しかし、私は上記の能力を達成することができるAPIを生産することができませんでした.スコープ関数の実装
方法の制限についての議論で、最初に実装を議論しましょう.
run
(非拡張機能として)実装するのが最も簡単です.それは単に戻り型を持ついくつかの文の「ラッパー」ブロックです.小林で
run
isinline fun <R> run(block: () -> R): R = block()
ダーツでも同様にR run<R>(R Function() block) => block();
let
コリンではinline fun <T, R> T.let(block: (T) -> R): R = block(this)
DARTでは、拡張メソッド構文を使用する必要がありますextension ScopeFunctionLet<T extends Object> on T {
R let<R>(R Function(T self) block) => block(this);
}
最後にalso
コリンではinline fun <T> T.also(block: (T) -> Unit): T {
block(this)
return this
}
ダーツでextension ScopeFunctionAlso<T extends Object> on T {
T also(void Function(T self) block) {
block(this);
return this;
}
}
ユースケース
使用例
つの異なる米国のケースがあります
let
:void main1() {
// First use case
["one", "one", "two", "three", "four", "five"]
.map((String it) => it.length)
.where((int it) => it > 3)
.let((Iterable<int> it) => print('Number of results: ${it.length}'));
// Second use case
'Hey there!'?.let((it) => it.length);
// Third use case
["one", "one", "two", "three", "four", "five"]
.first
.let((it) => it.length < 5 ? '!' : it);
}
void main2() {
// First use case without "let"
final numbers = ["one", "one", "two", "three", "four", "five"]
.map((String it) => it.length)
.where((int it) => it > 3);
print('Number of results: ${numbers.length}');
// Second use case without let
final String? nullableString = 'Hey there!';
if (nullableString != null) {
nullableString.length;
}
// Third use case without let
var firstElement = ["one", "one", "two", "three", "four", "five"]
.first;
if (firstElement.length < 5) {
firstElement = '!';
}
}
使用事例
非拡大
run
式が必要ないくつかの文のブロックを実行します.void main3() {
final hexNumberRegex = run(() {
final digits = '0-9';
final hexDigits = 'a-fA-F';
return RegExp('[$digits$hexDigits]+');
});
final matches = hexNumberRegex
.allMatches("+123 -FFFF !%*& 88 XYZ")
.map((RegExpMatch match) => match.group(0));
print(matches); // '123', 'FFFF', '88'
}
使用例
also
and apply
技術的に同じですが、違いは文脈オブジェクトであるということですalso
レシーバの代わりに引数として利用できます.コンテキストオブジェクトを引数として扱うアクションを実行するときに使用されます.これは、アクションがプロパティ/メソッドではなくオブジェクトへの参照を必要とする場合です.[3, 1, 5].also((it) => it.sort()).add(6);
ソース
ライブラリへのソースコードはGithubアカウントで利用可能です.現時点では利用できません
pub.dev
, むしろGitの依存関係です.Reference
この問題について(Kuにおけるスコープ関数), 我々は、より多くの情報をここで見つけました https://dev.to/sunderee/kotlin-scope-functions-in-dart-41ffテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol