DartとKotlinの違い
14139 ワード
Dart
ベースデータ型
Dartの主なタイプは以下のとおりです. numの数値には2つのサブタイプがあります. int:任意の長さの整数 double:デュアル精度浮動小数点数 String DartにおけるString付与値は、 bool bool値は対応する値であり、非bool値はfalse である. List Map
変数宣言
言語
変数#ヘンスウ#
コンパイル時定数
定数
Dart
具体的なタイプ、var
const(変数)
final(変数)
Kotlin
var
const val
val
関数#カンスウ#
Dartでは、関数もオブジェクトであり、戻り値が指定されていない場合は
関数宣言には、次の方法があります.
関数の別名
オプションのパラメータ
Dartは2つのオプションパラメータをサポートします.位置オプションパラメータ(廃棄済み)は ネーミングオプションパラメータは を使用する.
この2つのオプションパラメータ方式はPSを同時に使用することはできません:後者の言語として、Kotlinオプションパラメータの2つの方式はいずれもサポートされていますが、
オペレータとプロセス制御文
DartのほとんどのコンテンツはC++、Javaと変わりません.次は前の2つとは異なるオペレータです.
整頓オペレータ
カスケード
単一オブジェクトの一連の操作が必要な場合は、カスケードオペレータ
if
ループ
通常、forループは従来と一致し、反復オブジェクトがコンテナである場合、
Swicth Case
switchのパラメータはStringまたはnumであってもよい.文の内容が空であれば、
異常
Dartでは、空でないオブジェクトを例外として放出できます.catchにタイプが指定されていない場合は、varのような任意のタイプの例外を処理できます.残りはJavaと似ています.
クラスとオブジェクト
DartはJavaと一致し、すべてのオブジェクトがクラスのインスタンスであり、すべてのクラスが
Dart 2では、
コンストラクション関数での値伝達および構築定数
コンストラクション関数実行プロセス:
プロセスは、Exオブジェクトが作成される->Ex初期化リストを呼び出す->Base初期化リストを呼び出す->Base構築方法の内容を呼び出す->Ex構築方法を呼び出す
ファクトリコンストラクション関数:ファクトリコンストラクション関数はstatic静的変数と類似しており、thisポインタにアクセスできません.ファクトリコンストラクション関数は
Get Setメソッド
クラスの各フィールドは暗黙的なGetterとSetterに対応し、呼び出しはKotlinと一致します.デフォルト呼び出しは、
抽象クラス
Dartではインタフェースとクラスが統一されており,クラスはインタフェースであり,Javaと
いずれもインタフェースですが、継承と実装はJavaと似ています.継承キーワードは実装を使用すると、子クラスは親クラスのパラメータにアクセスできず、C++の純虚関数に似ていますが、複数のクラスの複数の関数を実装できます. DartはJavaと一致し、単一継承方式を採用し、サブクラスは親非プライベート変数を継承することができる.
かき混ぜる
StringBuffer
文字列結合クラス:
ようき
Dartのコンテナは主にList,Set,Mapを含み,Javaの用法とほぼ一致する.
List
Set
Map
コンテナの反復
List,MapはいずれもEfficientLengthIterableから継承されており反復可能であり,Set自身はforEach法を実現しているので,以上の3つの容器はいずれも
ライブラリのインポート
インポートする唯一の必須パラメータは、指定したライブラリのURIです.内蔵ライブラリの場合、インポートには特別なURI:dart:schemeが必要です.他のライブラリでは、ファイルのシステムパスやpackage:schemeのようなフォーマットを使用できます.
接頭辞
2つのライブラリで競合する名前をインポートする場合は、接頭辞を追加することで区別できます.
部分インポート
インポートの遅延
次の場合、インポートを遅らせる必要がある場合があります.起動時間を短縮 A/Bテスト は、使用する機能が少ない をロードする.
非同期
Dartライブラリには、通常、I/O、ネットワークリクエストなどの時間のかかる操作を設定した後、メソッドの実行が完了するのを待つことなく、FutureオブジェクトとStreamオブジェクトを返す方法がたくさんあります.
Future
Futureを使用して完了した値を実行する必要がある場合は、次の2つの選択肢があります. FutureのAPIを使用してFutureの .
Stream
Streamから値を取得するには、次の2つのオプションがあります. asyncと非同期ループ(await for) ストリームが1つの値を読み出すのを待つ. 値を循環本体内に入れて実行する. ループは、Streamがオフになるまで1、2ステップを実行します.
リスニングを終了する必要がある場合、 Stream APIを使用してStreamクラスの Generators
一連の値の送信を遅延する必要がある場合は、同期生成=>Iterableオブジェクトを返す: 非同期生成=>Streamオブジェクトを返します: ジェネレータが再帰的に呼び出された場合、yield*を使用して効率を向上させることができます: 呼び出し可能クラス
クラスをメソッドのように呼び出す必要がある場合は、
隔離区域
マルチコアCPUの利点を十分に発揮するために、通常は共有メモリのスレッドを同時に実行するが、共有状態の同時実行はエラーが発生しやすく、コードの複雑化を招く可能性が高い.Dartコードは、他の分離領域から分離領域にアクセスしない状態を確保するために、各分離領域に独自のメモリスタックがあります.
注釈
ベースデータ型
Dartの主なタイプは以下のとおりです.
$
を使用して値挿入を行うことができない点で、単一の二重引用符を使用することができます.このほか、三重引用符を使用して、複数行の文字列の割り当てを行うこともできます.(Kotlinと同様に、Kotlinには単一引用符がない唯一の違いです).String文字列では、Javaとは異なる\
がデフォルトでエスケープ効果を有し、\
のエスケープ作用を回避するには、文字列宣言の前にr
、すなわちString s = r"
"
を加える必要がある.変数宣言
言語
変数#ヘンスウ#
コンパイル時定数
定数
Dart
具体的なタイプ、var
const(変数)
final(変数)
Kotlin
var
const val
val
関数#カンスウ#
Dartでは、関数もオブジェクトであり、戻り値が指定されていない場合は
null
、すなわち
を返す.関数宣言には、次の方法があります.
//
String sayHello(String name){
println("Hello, $name");
}
// , :
sayHello(name){
println("Hello, $name");
}// , ,
// , '=>' (Kotlin '=')
sayHello(name) => println("Hello, $name");
// ,
var sayHello = (name) => println("Hello, $name");
関数の別名
//
// typedef ( )
typedef void sayHello(String hellow)
//
// Kotlin ( ) ->
オプションのパラメータ
Dartは2つのオプションパラメータをサポートします.
[]
を使用し、デフォルト値は:
賦値、すなわち//
String sayHello(String name, [String greetings : 'Hello']) => println("$greetings, $name")
//
sayHello('name', 'hello')
を採用するが、この場合、位置オプションパラメータが多くなると、どのオブジェクトがどのオプションパラメータに対応するかを判別することは困難である.{}
、デフォルト値は=
、すなわち//
String sayHello(String name, {String greetings = 'Hello'}) => print("$greetings, $name")
//
sayHello('name', greetings = 'hello')
この2つのオプションパラメータ方式はPSを同時に使用することはできません:後者の言語として、Kotlinオプションパラメータの2つの方式はいずれもサポートされていますが、
{}
、[]
は必要ありません.オペレータとプロセス制御文
DartのほとんどのコンテンツはC++、Javaと変わりません.次は前の2つとは異なるオペレータです.
整頓オペレータ
~/
C++、Javaで整数演算子がないのは、整数を除いた場合のデフォルトの結果が整数であり、Dartでは実際の結果が返されるためです.int a = 3;
int b = 2;
print(a / b); // 1.5
print(a ~/ b); // 1
カスケード
単一オブジェクトの一連の操作が必要な場合は、カスケードオペレータ
..
(Kotlinのapply拡張関数に対応)を使用します.class Person {
String firstName;
String lastName;
}
Person p = Person(); // new
p .. firstName = 'firstName'
.. lastName = 'lastName';
if
if
は通常の用法と一致するが、bool以外の値を判断するとcheckモードで異常が放出され、productionモードではfalseと見なされる.ループ
通常、forループは従来と一致し、反復オブジェクトがコンテナである場合、
forEach((T) -> function)
メソッドを使用して反復することができる.Swicth Case
switchのパラメータはStringまたはnumであってもよい.文の内容が空であれば、
break
を省略して空にする(次の文の内容を実行する)効果を達成することができる.空でなくても空になりたい場合は、手動でラベルを指定し、continue
を使用してラベルを返す必要があります.switch(0){
case 0:
case 1:
print(' ');
break;
case 2:
print(' ');
continue closed;
case 3:
print('x');
break;
closed:
case 4:
print(' ');
break;
}
異常
Dartでは、空でないオブジェクトを例外として放出できます.catchにタイプが指定されていない場合は、varのような任意のタイプの例外を処理できます.残りはJavaと似ています.
クラスとオブジェクト
DartはJavaと一致し、すべてのオブジェクトがクラスのインスタンスであり、すべてのクラスが
Object
のサブクラスである(KotlinはAny
).Dart 2では、
new
およびconst
のキーワードを省略してオブジェクトを作成できます.コンストラクション関数での値伝達および構築定数
class Person {
String firstName;
String lastName;
//
Person(this.firstName, String lastName){
this.lastName = lastName;
}
// final ,
//
Person(String a, String b) : firstName = a, lastName = b;
//
const Person(this.firstName, this.lastName);
//
Person.polar(this.lastName, this.firstName)
Person(String firstName, String lastName) : this.polar(lastName, firstName)
}
コンストラクション関数実行プロセス:
class Base {
int a;
int b;
Base(this.a, int c) {
b = c;
}
}
class Ex : Base {
int d;
Ex(a, b , this.d) : super(a, b){
}
}
プロセスは、Exオブジェクトが作成される->Ex初期化リストを呼び出す->Base初期化リストを呼び出す->Base構築方法の内容を呼び出す->Ex構築方法を呼び出す
ファクトリコンストラクション関数:ファクトリコンストラクション関数はstatic静的変数と類似しており、thisポインタにアクセスできません.ファクトリコンストラクション関数は
factory
接頭辞で始まり、初期化リストまたは初期化形式パラメータがない可能性があります.逆に、オブジェクトを返す関数体が必要です.class A {
String name;
static A cache;
factory A(String name){
if(cache == null){
A.cache = new A.newObject(name);
}
return A.cache;
}
}
Get Setメソッド
クラスの各フィールドは暗黙的なGetterとSetterに対応し、呼び出しはKotlinと一致します.デフォルト呼び出しは、
get
およびset
のキーワードを使用して拡張できます.フィールドがfinal
またはconst
の場合、Getterメソッドのみが使用されます.class Person {
String firstName;
String lastName;
// get
String get firstName => firstName + lastName;
// set
set lastName => lastName = value
}
抽象クラス
Dartではインタフェースとクラスが統一されており,クラスはインタフェースであり,Javaと
abstract
メソッドを用いて抽象クラスを定義し,抽象クラスはインスタンス化できない.いずれもインタフェースですが、継承と実装はJavaと似ています.継承キーワードは
extends
,実装キーワードはimplements
である.かき混ぜる
Mixins
は、異なるクラスでコード再利用を行うための方法である.Mixins
クラスを宣言するには、Objectから継承された構築メソッド(抽象クラス)のないクラスを作成する必要があります.abstract class MixinsExample {
bool isSelected = false;
void printCurrentState(){
if(isSelected){
print('Current state is selected');
}else{
print('Current state is unselected');
}
}
}
with
キーワードで使用:class Content with MixinsExample{
...
}
StringBuffer
文字列結合クラス:
StringBuffer sb = new StringBuffer();
sb.write("first");
sb.writeAll(['array1', 'array2']);
print(sb.toString());
sb.clear();
ようき
Dartのコンテナは主にList,Set,Mapを含み,Javaの用法とほぼ一致する.
List
//
List count = new List();
//
List from = [3, 2, 1];
//
varfrom = [3, 2, 1];
count.add(0);
count.addAll(from);
count.length; // 4
count[0]; // 0
// , < 0 , = 0 , > 0
count.sort((a, b) => a - b); // [0, 1, 2, 3]
count.remove(3); // 3
count.indexOf(2); // 2
count.removeAt(1); // 1
count.removeWhere((i) => i == 0); // 0
count.clear(); // count.length 0
Set
Set set = new Set();
set.addAll(['first', 'second', "third"]);
set.length; // 3
set.remove('second'); // true
set.contains('third'); // true
Set newSet = new Set.from(['third', 'forth']);
//
Set intersection = set.inersection(newSet);
//
intersection.isSubsetOf(set); // true
Map
Map> map = {
'key1': ['array01', 'array02'],
'key2': ['array11', 'array12']
};
//
var map = >{
'key1': ['array01', 'array02'],
'key2': ['array11', 'array12']
};
Map sMap = new Map();
sMap['key'] = 'value';
sMap.containsKey('key'); // true
sMap.keys; // ['key']
sMap.values; // ['value']
sMap.remove('key'); // 'value'
コンテナの反復
List,MapはいずれもEfficientLengthIterableから継承されており反復可能であり,Set自身はforEach法を実現しているので,以上の3つの容器はいずれも
forEach((T) => function)
とfor(t in collection)
で反復可能である.ライブラリのインポート
インポートする唯一の必須パラメータは、指定したライブラリのURIです.内蔵ライブラリの場合、インポートには特別なURI:dart:schemeが必要です.他のライブラリでは、ファイルのシステムパスやpackage:schemeのようなフォーマットを使用できます.
接頭辞
2つのライブラリで競合する名前をインポートする場合は、接頭辞を追加することで区別できます.
// Element
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
Element element1 = Element();
Element element2 = lib2.Element();
部分インポート
import 'package:lib1/lib1.dart' show func;
import 'package:lib2/lib2.dart' hide func;
インポートの遅延
次の場合、インポートを遅らせる必要がある場合があります.
import 'package:greetings/hello.dart' deferred as greeting;
Future greet() async{
//
await gretting.loadLibrary();
gretting.greet();
}
非同期
Dartライブラリには、通常、I/O、ネットワークリクエストなどの時間のかかる操作を設定した後、メソッドの実行が完了するのを待つことなく、FutureオブジェクトとStreamオブジェクトを返す方法がたくさんあります.
Future
Futureを使用して完了した値を実行する必要がある場合は、次の2つの選択肢があります.
async
とawait
async
とawait
は非同期であるが、コード的には同期動作のように見え、より理解しやすい:// await async
Future checkVersion() async{
// await , Future
// await
var version = await lookUpVersion();
...
}
then(function)
を使用してFutureが完了した後に実行する必要があるコードを設定する:// Future
HttpRequest.getString(url)
.then((String result) {
print(result);
}).catchError(e){
...
};
then(function)
メソッドも有効な非同期メソッドを順次実行する方法を提供する:// Future
constlyQuery(url)
.then((value) => expensiveWork(value))
.then((_) => lengthyComputation())
.then((_) => print('Done'))
.catchError(e){
...
};
// async await
request() async {
try{
final value = await constlyQuery(url);
await expensiveWork(value);
await lengthyComputation();
print('Done');
}catch(e){
...
}
}
// ,
Future delete() async => ...
Future add() async => ...
Future select() async => ...
doJobs() async {
await Future.wait([
delete(),
add(),
select()
]);
print('Done');
}
Stream
Streamから値を取得するには、次の2つのオプションがあります.
Future main() async {
await for(varOfType identifier in expression){
...
}
}
を使用する非同期ループの式には、次のようなStreamタイプが必要です.リスニングを終了する必要がある場合、
break
またはreturn
を使用して、ループを終了し、Streamのリスニングをキャンセルする.listen()
メソッドを使用して、各ファイルまたはディレクトリを処理する関数を入力してファイルリストを購読する:void main(List arguments) {
// ...
FileSystemEntity.isDirectory(searchPath).then((isDir) {
if (isDir) {
final startingDir = Directory(searchPath);
startingDir
.list(
recursive: argResults[recursive],
followLinks: argResults[followLinks])
.listen((entity) {
if (entity is File) {
searchFile(entity, searchTerms);
}
});
} else {
searchFile(File(searchPath), searchTerms);
}
});
}
// async await for
Future main(List arguments) async {
// ...
if (await FileSystemEntity.isDirectory(searchPath)) {
final startingDir = Directory(searchPath);
await for (var entity in startingDir.list(
recursive: argResults[recursive],
followLinks: argResults[followLinks])) {
if (entity is File) {
searchFile(entity, searchTerms);
}
}
} else {
searchFile(File(searchPath), searchTerms);
}
}
//
Future readFileAwaitFor() async {
var config = File('config.txt');
Stream> inputStream = config.openRead();
var lines = inputStream
//
.transform(utf8.decoder)
.transform(LineSplitter());
try {
await for (var line in lines) {
print('Got ${line.length} characters from stream');
}
print('file is now closed');
} catch (e) {
print(e);
}
}
一連の値の送信を遅延する必要がある場合は、
generator function
を使用します.Iterable naturalsTo(int n) sync* {
int k = 0;
while(k < n)
// yield
yield k++;
}
Stream naturalsTo(int n) async* {
int k = 0;
while(k < n)
// yield
yield k++;
}
Iterable naturalsTo(int n) sync* {
if(n > 0){
yield n;
yield* naturalsDownFrom(n - 1);
}
}
クラスをメソッドのように呼び出す必要がある場合は、
call
メソッドを実装します.class FuctionLike{
call(String a, String b, String c) => "$a, $b, $c"
}
main(){
var fl = FunctionLike();
var out = fl('a', 'b', 'c'); // 'a, b, c'
}
隔離区域
マルチコアCPUの利点を十分に発揮するために、通常は共有メモリのスレッドを同時に実行するが、共有状態の同時実行はエラーが発生しやすく、コードの複雑化を招く可能性が高い.Dartコードは、他の分離領域から分離領域にアクセスしない状態を確保するために、各分離領域に独自のメモリスタックがあります.
注釈
//
class Todo {
final String who;
final String what;
const Todo(this.who, this.what);
}
//
@Todo('name', 'job')
void doSomething {
print('do something');
}