Flutter Linter Kuralları Bölüm 2: Stil Kuralları 💫 🌌 ✨
Gülsen Keskin
Posted on February 20, 2022
Bir önceki bölümde Linter kurallarının ilk grubu olan hata kurallarını öğrenmiştik. Bu bölümde ikinci grupta yer alan stil kurallarına değineceğiz.
Stil Kuralları:
always_declare_return_types
Fonksiyon veya method dönüş türlerini belirtin:
Bir method veya fonksiyon oluştururken her zaman bir dönüş türü belirtin. Fonksiyonlar için dönüş türleri bildirmek, analyzer'ın çalışma zamanı sırasında oluşabilecek hatalar için kodunuzu daha iyi bir şekilde kontrol etmesine izin vererek kod tabanınızı iyileştirmeye yardımcı olur.
Yanlış kullanım:
main() { }
_bar() => _Foo();
class _Foo {
_foo() => 42;
}
Doğru kullanım:
void main() { }
_Foo _bar() => _Foo();
class _Foo {
int _foo() => 42;
}
typedef predicate = bool Function(Object o);
always_put_control_body_on_new_line
Bir if, for, while do'nun ifade kısmını kısa olsa bile expression ile aynı satıra koymayın.
Yanlış kullanım:
if (notReady) return;
if (notReady)
return;
else print('ok')
while (condition) i += 1;
Doğru kullanım:
if (notReady)
return;
if (notReady)
return;
else
print('ok')
while (condition)
i += 1;
always_put_required_named_parameters_first
Required olarak tanımladığınız parametreleri her zaman en başa koyun:
Yanlış kullanım: m({b, c, required a}) ;
Doğru kullanım: m({required a, b, c}) ;
Yanlış kullanım: m({b, c, @required a}) ;
Doğru kullanım: m({@required a, b, c}) ;
always_specify_types
Tip açıklamalarını belirtin. Mümkün olduğunca var kullanmaktan kaçının.
Türün bilinmediğini açıkça belirtmek istiyorsanız dynamic kullanın.
Yanlış kullanım:
var foo = 10;
final bar = Bar();
const quux = 20;
Doğru kullanım:
int foo = 10;
final Bar bar = Bar();
String baz = 'hello';
const int quux = 20;
annotate_overrides
Override edilen medhod ve field'lara açıklama ekleyin.
Yanlış kullanım:
class Cat {
int get lives => 9;
}
class Lucky extends Cat {
final int lives = 14;
}
Doğru kullanım:
abstract class Dog {
String get breed;
void bark() {}
}
class Husky extends Dog {
@override
final String breed = 'Husky';
@override
void bark() {}
}
avoid_annotating_with_dynamic
Dinamik, bir fonksiyon veya methodun varsayılan dönüş değeri olduğundan, bunu belirtmeye gerek yoktur.
Yanlış kullanım:
dynamic lookUpOrDefault(String name, Map map, dynamic defaultValue) {
var value = map[name];
if (value != null) return value;
return defaultValue;
}
Doğru kullanım:
lookUpOrDefault(String name, Map map, defaultValue) {
var value = map[name];
if (value != null) return value;
return defaultValue;
}
avoid_bool_literals_in_conditional_expressions
Koşullu ifadelerde (conditional expressions) bool kullanımından kaçının.
Yanlış kullanım:
condition ? true : boolExpression
condition ? false : boolExpression
condition ? boolExpression : true
condition ? boolExpression : false
Doğru kullanım:
condition || boolExpression
!condition && boolExpression
!condition || boolExpression
condition && boolExpression
avoid_catches_without_on_clauses
Yan tümce olmadan catch kullanımından kaçının.
Ön yan tümceleri olmadan catch kullanmak, kodunuzu atılamayan(thrown) (ve dolayısıyla fark edilmeyecek) beklenmedik hatalarla karşılaşmaya yatkın hale getirir.
Yanlış kullanım:
try {
somethingRisky()
}
catch(e) {
doSomething(e);
}
Doğru kullanım:
try {
somethingRisky()
}
on Exception catch(e) {
doSomething(e);
}
avoid_catching_errors
Hatayı veya onu implemente eden türleri açıkça yakalamayın.
Hatalar, Exception'lardan farklıdır, çünkü Hatalar çalışma zamanından önce analiz edilebilir ve önlenebilir. Çalışma zamanında bir hatayı yakalamak (catch) neredeyse hiçbir zaman gerekmez.
Yanlış kullanım:
try {
somethingRisky();
} on Error catch(e) {
doSomething(e);
}
Doğru kullanım:
try {
somethingRisky();
} on Exception catch(e) {
doSomething(e);
}
avoid_classes_with_only_static_members
Yalnızca statik üyeler içeren bir sınıf tanımlamaktan kaçının.
Yanlış kullanım:
class DateUtils {
static DateTime mostRecent(List<DateTime> dates) {
return dates.reduce((a, b) => a.isAfter(b) ? a : b);
}
}
class _Favorites {
static const mammal = 'weasel';
}
Doğru kullanım:
DateTime mostRecent(List<DateTime> dates) {
return dates.reduce((a, b) => a.isAfter(b) ? a : b);
}
const _favoriteMammal = 'weasel';
avoid_double_and_int_checks
Double ve int kontrollerinden kaçının.
JS'ye derlendiğinde integer değerler float olarak temsil edilir. Bu durum türün int veya double olduğu yerlerde, is or is'i kullanırken bazı beklenmedik davranışlara yol açabilir.
Yanlış kullanım:
f(num x) {
if (x is double) {
...
} else if (x is int) {
...
}
}
Doğru kullanım:
f(dynamic x) {
if (x is num) {
...
} else {
...
}
}
avoid_equals_and_hash_code_on_mutable_classes
@immutable olarak işaretlenmemiş sınıflarda aşırı yükleme operatörü (overloading) == ve hashCode kullanımından kaçının.
Bir sınıf immutable (değişmez) değilse, overloading operator (aşırı yükleme operatörü) == ve hashCode, koleksiyonlarda kullanıldığında öngörülemeyen ve istenmeyen davranışlara yol açabilir.
Yanlış kullanım:
class B {
String key;
const B(this.key);
@override
operator ==(other) => other is B && other.key == key;
@override
int hashCode() => key.hashCode;
}
Lint, @immutable notunun kullanımını kontrol eder ve sınıf başka türlü değiştirilemez olsa bile tetiklenir. Böylece:
Yanlış kullanım:
class C {
final String key;
const C(this.key);
@override
operator ==(other) => other is B && other.key == key;
@override
int hashCode() => key.hashCode;
}
Doğru kullanım:
@immutable
class A {
final String key;
const A(this.key);
@override
operator ==(other) => other is A && other.key == key;
@override
int hashCode() => key.hashCode;
}
avoid_escaping_inner_quotes
Kesme işareti kullanmanız gerekiyorsa string ifadenizi " çift tırnak içerisinde yazın. Tek tırnak kullanmayın.
Yanlış kullanım: var s = 'It\'s not fun';
Doğru kullanım: var s = "It's not fun";
avoid_field_initializers_in_const_classes
Const sınıflarında final başlatıcılarını kullanmaktan kaçının.
Yanlış kullanım:
class A {
final a = const [];
const A();
}
Doğru kullanım:
class A {
get a => const [];
const A();
}
avoid_final_parameters
Parametre bildirimlerinde final kullanmaktan kaçının.
Yanlış kullanım:
void goodParameter(final String label) { // LINT
print(label);
}
Doğru kullanım:
void badParameter(String label) { // OK
print(label);
}
Yanlış kullanım: void goodExpression(final int value) => print(value); // LINT
Doğru kullanım:void badExpression(int value) => print(value); // OK
Yanlış kullanım:void badExpression(int value) => print(value); // OK
Doğru kullanım:[1, 4, 6, 8].forEach((value) => print(value + 2)); // OK
avoid_function_literals_in_foreach_calls
Function literal ile forEach kullanımından kaçının.
Yanlış kullanım:
people.forEach((person) {
...
});
Doğru kullanım:
for (var person in people) {
...
}
people.forEach(print);
avoid_init_to_null
Değişkenleri null ataması yaparak başlatmayın.
Dart'ta değer ataması yapılmayan bir değişken otomatik olarak null olarak başlatılır. Bu sebeple null ataması yapmak gereksizdir.
Yanlış kullanım:
int _nextId = null;
class LazyId {
int _id = null;
int get id {
if (_nextId == null) _nextId = 0;
if (_id == null) _id = _nextId++;
return _id;
}
}
Doğru kullanım:
int _nextId;
class LazyId {
int _id;
int get id {
if (_nextId == null) _nextId = 0;
if (_id == null) _id = _nextId++;
return _id;
}
}
avoid_js_rounded_ints
Yanlış kullanım: int value = 9007199254740995;
Doğru kullanım: BigInt value = BigInt.parse('9007199254740995');
avoid_multiple_declarations_per_line
Tek bir satırda birden çok değişken tanımlamayın.
Yanlış kullanım: String? foo, bar, baz;
Doğru kullanım:
String? foo;
String? bar;
String? baz;
avoid_null_checks_in_equality_operators
Null özel bir tür olduğundan, hiçbir sınıf ona eşdeğer olamaz. Bu nedenle, diğer örneğin boş olup olmadığını kontrol etmek gereksizdir.
Yanlış kullanım:
class Person {
final String name;
@override
operator ==(other) =>
other != null && other is Person && name == other.name;
}
Doğru kullanım:
class Person {
final String name;
@override
operator ==(other) => other is Person && name == other.name;
}
avoid_positional_boolean_parameters
Konumsal bool parametrelerini kullanmaktan kaçının.Bunun yerine adlandırılmış bool parametrelerini kullanın.
Yanlış kullanım:
Task(true);
Task(false);
ListBox(false, true, true);
Button(false);
Doğru kullanım:
Task.oneShot();
Task.repeating();
ListBox(scroll: true, showScrollbars: true);
Button(ButtonState.enabled);
avoid_private_typedef_functions
Yalnızca bir kez kullanılan özel typedef fonksiyonlarından kaçının. Satır içi işlev sözdizimini (inline function syntax) tercih edin.
Yanlış kullanım:
typedef void _F();
m(_F f);
Doğru kullanım:m(void Function() f);
avoid_redundant_argument_values
Fonksiyon parametresinin default değerine karşılık gelen argümanlar göndermekten kaçının.
Yanlış kullanım:
void f({bool valWithDefault = true, bool? val}) {
...
}
void main() {
f(valWithDefault: true);
}
Doğru kullanım:
void f({bool valWithDefault = true, bool? val}) {
...
}
void main() {
f(valWithDefault: false);
f();
}
avoid_renaming_method_parameters
Override edilen methodların parametrelerini yeniden adlandırmayın.
Yanlış kullanım:
abstract class A {
m(a);
}
abstract class B extends A {
m(b); <---
}
Doğru kullanım:
abstract class A {
m(a);
}
abstract class B extends A {
m(a); <----
}
avoid_return_types_on_setters
Setter'larda dönüş türü belirtmekten kaçının.
Setter'lar bir değer döndürmediğinden, dönüş türü belirtmek gereksizdir.
Yanlış kullanım: void set speed(int ms);
Doğru kullanım: set speed(int ms);
avoid_returning_null
Dönüş türü bool, double, int veya num olan üyelerden null döndürmekten kaçının.
bool, double, int ve num gibi primitive (ilkel) türleri döndüren işlevlerin genellikle null olmayan değerler döndürmesi beklenir. Bu nedenle, primitive bir türün beklendiği yerde null döndürmek, runtime exception'larına (çalışma zamanı istisnalarına) yol açabilir.
Yanlış kullanım:
bool getBool() => null;
num getNum() => null;
int getInt() => null;
double getDouble() => null;
Doğru kullanım:
bool getBool() => false;
num getNum() => -1;
int getInt() => -1;
double getDouble() => -1.0;
avoid_returning_null_for_void
Void için null döndürmekten kaçının.
Yanlış kullanım:
void f1() {
return null;
}
Future<void> f2() async {
return null;
}
Doğru kullanım:
void f1() {
return;
}
Future<void> f2() async {
return;
}
avoid_returning_this
this yerine cascade operator'ünü kullanın.
Yanlış kullanım:
var buffer = StringBuffer()
.write('one')
.write('two')
.write('three');
Doğru kullanım:
var buffer = StringBuffer()
..write('one')
..write('two')
..write('three');
avoid_setters_without_getters
Karşılık gelen bir getter değeri olmadan bir setter tanımlamayın.
Yanlış kullanım:
class Bad {
int l, r;
set length(int newLength) {
r = l + newLength;
}
}
Doğru kullanım:
class Good {
int l, r;
int get length => r - l;
set length(int newLength) {
r = l + newLength;
}
}
avoid_shadowing_type_parameters
Shadowing tip parametrelerinden kaçının.
Yanlış kullanım:
class A<T> {
void fn<T>() {}
}
Doğru kullanım:
class A<T> {
void fn<U>() {}
}
avoid_types_on_closure_parameters
Function expression parametreleri için tür belirmek gereksizdir.
Yanlış kullanım:
var names = people.map((Person person) => person.name);
Doğru kullanım:
var names = people.map((person) => person.name);
avoid_unnecessary_containers
Gereksiz Container kullanımından kaçının.
Bir Widget öğesini başka hiçbir parametre seti olmadan Container ile sarmanın hiçbir etkisi yoktur ve kodu gereksiz yere daha karmaşık hale getirir.
Yanlış kullanım:
Widget buildRow() {
return Container(
child: Row(
children: <Widget>[
const MyLogo(),
const Expanded(
child: Text('...'),
),
],
)
);
}
Doğru kullanım:
Widget buildRow() {
return Row(
children: <Widget>[
const MyLogo(),
const Expanded(
child: Text('...'),
),
],
);
}
avoid_unused_constructor_parameters
Constructor'larda kullanılmayan parametre tanımlamaktan kaçının.
Yanlış kullanım:
class BadOne {
BadOne(int unusedParameter, [String unusedPositional]);
}
class BadTwo {
int c;
BadTwo(int a, int b, int x) {
c = a + b;
}
}
avoid_void_async
Void döndüren asenkron fonksiyonlardan kaçının.
Asenkron fonksiyonlarda geriye Future döndürün.
Yanlış kullanım:
void f() async {}
void f2() async => null;
Doğru kullanım:
Future<void> f() async {}
Future<void> f2() async => null;
await_only_futures
Await'e şu türlerde izin verilir: Future, FutureOr, Future?, FutureOr? ve dynamic.
Yanlış kullanım:
main() async {
print(await 23);
}
Doğru kulllanım:
main() async {
await null; // If a delay is really intended.
print(23);
}
camel_case_extensions
Uzantıları UpperCamelCase kullanarak adlandırın.
Uzantılar adlandırılırken, her kelimenin ilk harfin büyük yazmalı (ilk kelime dahil) ve seperator (ayırıcı) kullanmamalıdır.
Doğru kullanım:
extension MyFancyList<T> on List<T> {
// ...
}
extension SmartIterable<T> on Iterable<T> {
// ...
}
camel_case_types
Sınıflar ve typedef'ler isimlendirilirken her kelimenin ilk harfin (ilk kelime dahil) büyük yazmalı ve seperator kullanmamalıdır.
Doğru kullanım:
class SliderMenu {
// ...
}
class HttpRequest {
// ...
}
typedef num Adder(num x, num y);
cascade_invocations
Aynı referans üzerinde art arda methodlar çağırırken cascading (basamaklı) stili kullanın.
Yanlış kullanım:
SomeClass someReference = SomeClass();
someReference.firstMethod();
someReference.secondMethod();
Yanlış kullanım:
SomeClass someReference = SomeClass();
...
someReference.firstMethod();
someReference.aProperty = value;
someReference.secondMethod();
Doğru kullanım:
SomeClass someReference = SomeClass()
..firstMethod()
..aProperty = value
..secondMethod();
Doğru kullanım:
SomeClass someReference = SomeClass();
...
someReference
..firstMethod()
..aProperty = value
..secondMethod();
cast_nullable_to_non_nullable
Nullable olmayan bir türe nullable bir değer atamayın.
Yanlış kullanım:
class A {}
class B extends A {}
A? a;
var v = a as B;
var v = a as A;
Doğru kullanım:
class A {}
class B extends A {}
A? a;
var v = a! as B;
var v = a!;
constant_identifier_names
Constant isimlerinde lowerCamelCase kullanın.
Yanlış kullanım:
const PI = 3.14;
const kDefaultTimeout = 1000;
final URL_SCHEME = RegExp('^([a-z]+):');
class Dice {
static final NUMBER_GENERATOR = Random();
}
Doğru kullanım:
const pi = 3.14;
const defaultTimeout = 1000;
final urlScheme = RegExp('^([a-z]+):');
class Dice {
static final numberGenerator = Random();
}
deprecated_consistency
@deprecated()'ı Tutarlı bir şekilde uygulayın :
bir sınıf kullanımdan kaldırılmışsa (deprecated), constructor'ları da kullanımdan kaldırılmalıdır.
Bir field kullanımdan kaldırılmışsa, ona işaret eden constructor parametresi de kullanımdan kaldırılmalıdır.
Bir field'a işaret eden bir constructor parametresi kullanımdan kaldırılmışsa, field da kullanımdan kaldırılmalıdır.
Yanlış kullanım:
@deprecated
class A {
A();
}
class B {
B({this.field});
@deprecated
Object field;
}
Doğru kullanım:
@deprecated
class A {
@deprecated
A();
}
class B {
B({@deprecated this.field});
@deprecated
Object field;
}
directives_ordering
dart:
importlarını diğer importlardan önce yapın.
Yanlış kullanım:
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'dart:async'; // LINT
import 'dart:html'; // LINT
Doğru kullanım:
import 'dart:async'; // OK
import 'dart:html'; // OK
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
package:
importlarını relative importlarından önce yapın.
Yanlış kullanım:
import 'a.dart';
import 'b.dart';
import 'package:bar/bar.dart'; // LINT
import 'package:foo/foo.dart'; // LINT
Doğru kullanım:
import 'package:bar/bar.dart'; // OK
import 'package:foo/foo.dart'; // OK
import 'a.dart';
import 'b.dart';
Tüm import
'lardan sonra export
'ları ayrı bir bölümde belirtin.
Yanlış kullanım:
import 'src/error.dart';
export 'src/error.dart'; // LINT
import 'src/string_source.dart';
Doğru kullanım:
import 'src/error.dart';
import 'src/string_source.dart';
export 'src/error.dart'; // OK
Alfabetik sıralamayı kullanın.
Yanlış kullanım:
import 'package:foo/bar.dart'; // OK
import 'package:bar/bar.dart'; // LINT
import 'a/b.dart'; // OK
import 'a.dart'; // LINT
Doğru kullanım:
import 'package:bar/bar.dart'; // OK
import 'package:foo/bar.dart'; // OK
import 'a.dart'; // OK
import 'a/b.dart'; // OK
do_not_use_environment
Environment tarafından bildirilen değişkenleri kullanmayın.
Derleme zamanında environment'dan türetilen değerlerin kullanılması, gizli global durum yaratır ve uygulamaların anlaşılmasını ve sürdürülmesini zorlaştırır.
fromEnvironment veya hasEnvironment factory constructor'larını kullanmayın.
Yanlış kullanım:
const loggingLevel =
bool.hasEnvironment('logging') ? String.fromEnvironment('logging') : null;
empty_catches
Boş catch bloklarını kullanmaktan kaçının.
Genel olarak, boş catch bloklarını kullanmaktan kaçının. Bunun gerektiği durumlarda exception'ların neden yakalanıp bastırıldığını açıklamak için bir yorum yapılmalıdır. Alternatif olarak, exception tanımlayıcı (exception identifier), onu atlamak istediğimizi belirtmek için alt çizgilerle (örneğin, _) adlandırılabilir.
Yanlış kullanım:
try {
...
} catch(exception) { }
Doğru kullanım:
try {
...
} catch(e) {
// ignored, really.
}
// Alternatively:
try {
...
} catch(_) { }
// Better still:
try {
...
} catch(e) {
doSomething(e);
}
empty_constructor_bodies
Dart'ta, boş bir gövdeye sahip bir constructor yalnızca noktalı virgülle sonlandırılabilir. Bu const constructor'ları için gereklidir.
Doğru kullanım:
class Point {
int x, y;
Point(this.x, this.y);
}
Yanlış kullanım:
class Point {
int x, y;
Point(this.x, this.y) {}
}
eol_at_end_of_file
Dosya sonlarına yeni bir satır koyun.
Boş olmayan dosyaların sonuna tek bir yeni satır koyun.
Yanlış kullanım:
a {
}
Doğru kullanım:
b {
}
<-- newline
exhaustive_cases
Enum benzeri sınıflardaki tüm constant'lar için durum yan tümceleri (case clauses) tanımlayın.
Yanlış kullanım:
class EnumLike {
final int i;
const EnumLike._(this.i);
static const e = EnumLike._(1);
static const f = EnumLike._(2);
static const g = EnumLike._(3);
}
void bad(EnumLike e) {
// Missing case.
switch(e) { // LINT
case EnumLike.e :
print('e');
break;
case EnumLike.f :
print('f');
break;
}
}
Doğru kullanım:
class EnumLike {
final int i;
const EnumLike._(this.i);
static const e = EnumLike._(1);
static const f = EnumLike._(2);
static const g = EnumLike._(3);
}
void ok(EnumLike e) {
// All cases covered.
switch(e) { // OK
case EnumLike.e :
print('e');
break;
case EnumLike.f :
print('f');
break;
case EnumLike.g :
print('g');
break;
}
}
file_names
Bu makalede ayrıntılı olarak açıklandı.
implementation_imports
Uygulama dosyalarını başka bir paketten import etmeyin.
lib içindeki kitaplıklar herkese açıktır: diğer paketler bunları import etmekte serbesttir. Ancak bir paketin kodunun çoğu, yalnızca paketin kendisi tarafından import edilip kullanılması gereken dahili uygulama kitaplıklarıdır. Bunlar, lib'nin src adlı bir alt dizinine girer. İşleri düzenlemenize yardımcı olacaksa, orada alt dizinler oluşturabilirsiniz.
Aynı paketteki diğer Dart kodunun içinden lib/src'de yaşayan kitaplıkları içe aktarmakta özgürsünüz (lib'deki diğer kitaplıklar, bin içindeki komut dosyaları ve testler gibi) ancak asla başka bir paketin lib/src dizininden içe aktarmamalısınız. Bu dosyalar paketin genel API'sinin bir parçası değildir ve kodunuzu bozabilecek şekillerde değişebilirler.
Yanlış kullanım:
// In 'road_runner'
import 'package:acme/lib/src/internals.dart;
join_return_with_assignment
Mümkün olduğunda return deyimini atama ile birleştirin.
Yanlış kullanım:
class A {
B _lazyInstance;
static B get instance {
_lazyInstance ??= B(); // LINT
return _lazyInstance;
}
}
Doğru kullanım:
class A {
B _lazyInstance;
static B get instance => _lazyInstance ??= B();
}
leading_newlines_in_multiline_strings
Çok satırlı dizeleri yeni satırla başlatın.
Çok satırlı dizeler, yeni bir satırla başladıklarında okunması daha kolaydır (çok satırlı bir dizeyi başlatan yeni satır yok sayılır).
Yanlış kullanım:
var s1 = '''{
"a": 1,
"b": 2
}''';
Doğru kullanım:
var s1 = '''
{
"a": 1,
"b": 2
}''';
var s2 = '''This one-liner multiline string is ok. It usually allows to escape both ' and " in the string.''';
library_private_types_in_public_api
Genel API'lerde özel türleri kullanmaktan kaçının.
Yanlış kullanım:
f(_Private p) { ... }
class _Private {}
Doğru kullanım:
f(String s) { ... }
line_longer_than_80_chars
80 karakterden uzun satırlardan kaçının.
no_default_cases
Kötü kullanım:
switch (testEnum) {
case TestEnum.A:
return '123';
case TestEnum.B:
return 'abc';
default:
return null;
}
Doğru kullanım:
switch (testEnum) {
case TestEnum.A:
return '123';
case TestEnum.B:
return 'abc';
}
// Default here.
return null;
no_runtimeType_toString
runtimeType üzerinde "toString()" çağrısı yapmaktan kaçının.
Bir çalışma zamanı türünde toString'i çağırmak, performansı olumsuz yönde etkileyebilecek önemsiz bir işlemdir. Bundan kaçınmak daha iyidir.
Yanlış kullanım:
class A {
String toString() => '$runtimeType()';
}
Doğru kullanım:
class A {
String toString() => 'A()';
}
Bu durumun geçerli olmadığı performansın sorun olmadığı veya real type bilgilerinin performanstan daha önemli olduğu bazı istisnalara sahiptir:
assertion
throw expressions (atma ifadelerinde)
catch clauses (yakalama cümleciklerinde)
mixin declaration
abstract class (soyut sınıfta)
null_closures
Closure (kapanmanın) beklendiği bir argüman olarak null iletmeyin.
Yanlış kullanım: [1, 3, 5].firstWhere((e) => e.isOdd, orElse: null);
Doğru kullanım: [1, 3, 5].firstWhere((e) => e.isOdd, orElse: () => null);
omit_local_variable_types
Local değişkenler için tür açıklamalarını atlayın.
Local değişkenler, özellikle fonksiyonların küçük olma eğiliminde olduğu modern kodda çok az kapsama sahiptir. Türün atlanması, okuyucunun dikkatini değişkenin ismine ve onun başlangıç değerine odaklar.
Yanlış kullanım:
List<List<Ingredient>> possibleDesserts(Set<Ingredient> pantry) {
List<List<Ingredient>> desserts = <List<Ingredient>>[];
for (final List<Ingredient> recipe in cookbook) {
if (pantry.containsAll(recipe)) {
desserts.add(recipe);
}
}
return desserts;
}
Doğru kullanım:
List<List<Ingredient>> possibleDesserts(Set<Ingredient> pantry) {
var desserts = <List<Ingredient>>[];
for (final recipe in cookbook) {
if (pantry.containsAll(recipe)) {
desserts.add(recipe);
}
}
return desserts;
}
Bazen çıkarsanan tür, değişkenin sahip olmasını istediğiniz tür değildir. Örneğin, daha sonra başka türlerin değerlerini atamayı düşünebilirsin. Bu durumda, değişkene istediğiniz türde açıklama ekleyin.
Widget build(BuildContext context) {
[!Widget!] result = Text('You won!');
if (applyPadding) {
result = Padding(padding: EdgeInsets.all(8.0), child: result);
}
return result;
}
one_member_abstracts
Basit bir fonksiyon kullanılacaksa tek üyeli bir abstract (soyut ) sınıf tanımlamaktan kaçının.
Yanlış kullanım:
abstract class Predicate {
bool test(item);
}
Doğru kullanım: typedef Predicate = bool Function(item);
only_throw_errors
Yalnızca istisna (exception) veya Hata'yı genişleten (extending) sınıfların örneklerini atın.
Yalnızca dart.core.Error veya dart.core.Exception'ı genişleten sınıf örnekleri atın.
Hata veya istisna'yı extend etmeyen örnekler atmak kötü bir uygulamadır.
Yanlış kullanım:
void throwString() {
throw 'hello world!'; // LINT
}
Doğru kullanım:
void throwArgumentError() {
Error error = ArgumentError('oh!');
throw error; // OK
}
overriden_fields
Field'ları override etmeyin.
Yanlış kullanım:
class Base {
Object field = 'lorem';
Object something = 'change';
}
class Bad1 extends Base {
@override
final field = 'ipsum'; // LINT
}
class Bad2 extends Base {
@override
Object something = 'done'; // LINT
}
Doğru kullanım:
class Base {
Object field = 'lorem';
Object something = 'change';
}
class Ok extends Base {
Object newField; // OK
final Object newFinal = 'ignore'; // OK
}
Doğru kullanım:
abstract class BaseLoggingHandler {
Base transformer;
}
class LogPrintHandler implements BaseLoggingHandler {
@override
Derived transformer; // OK
}
package_api_docs
Tüm public API'ler için belge yorumları sağlayın.
Public (genel) API'ler, paketinizin lib klasöründeki her şeyden, lib/src'deki uygulama dosyalarının çıkarılması ve bir dışa aktarma yönergesiyle açıkça export edilen öğelerin eklenmesinden oluşur.
Örneğin lib/foo.dart:
export 'src/bar.dart' show Bar;
export 'src/baz.dart';
class Foo { }
class _Foo { }
Tüm public API üyeleri, ///belge-stili yorumlarla ( doc-style comments) belgelenmelidir.
Yanlış kullanım:
class Bar {
void bar();
}
Doğru kullanım:
/// A Foo.
abstract class Foo {
/// Start foo-ing.
void start() => _start();
_start();
}
package_prefixed_library_names
Bu kılavuz, iki kitaplık aynı ada sahip olduğunda alınan uyarılardan kaçınmanıza yardımcı olur. Önerilen kurallar:
Paket adının önüne tüm kitaplık adlarını ekleyin.
Giriş kitaplığının paketle aynı ada sahip olmasını sağlayın.
Bir paketteki diğer tüm kitaplıklar için, paket adından sonra kitaplığın Dart dosyasına noktayla ayrılmış yolu ekleyin.
lib altındaki kitaplıklar için üst dizin adını atlayın.
Örneğin, paket adının my_package olduğu paketteki çeşitli dosyalar için kitaplık adları şunlardır:
// In lib/my_package.dart
library my_package;
// In lib/other.dart
library my_package.other;
// In lib/foo/bar.dart
library my_package.foo.bar;
// In example/foo/bar.dart
library my_package.example.foo.bar;
// In lib/src/private.dart
library my_package.src.private;
parameter_assignments
Fonksiyon veya methodların parametrelerine yeni değerler atamayın.
??= gibi bir operatör kullanılmadığı sürece, parametrelere yeni değerler atamak genellikle kötü bir uygulamadır. Aksi takdirde, parametreleri keyfi olarak yeniden atamak bir hatadır.
Yanlış kullanım:
void badFunction(int parameter) { // LINT
parameter = 4;
}
Yanlış kullanım:
void badFunction(int required, {int optional: 42}) { // LINT
optional ??= 8;
}
Yanlış kullanım:
void badFunctionPositional(int required, [int optional = 42]) { // LINT
optional ??= 8;
}
Yanlış kullanım:
class A {
void badMethod(int parameter) { // LINT
parameter = 4;
}
}
Doğru kullanım:
void ok(String parameter) {
print(parameter);
}
Doğru kullanım:
void actuallyGood(int required, {int optional}) { // OK
optional ??= ...;
}
Doğru kullanım:
void actuallyGoodPositional(int required, [int optional]) { // OK
optional ??= ...;
}
Doğru kullanım:
class A {
void ok(String parameter) {
print(parameter);
}
}
prefer_adjacent_string_concatenation
prefer_adjacent_string_concatenation
String birleştirme için string literal'i kullanın.
Yanlış kullanım:
raiseAlarm(
'ERROR: Parts of the spaceship are on fire. Other ' +
'parts are overrun by martians. Unclear which are which.');
Doğru kullanım:
raiseAlarm(
'ERROR: Parts of the spaceship are on fire. Other '
'parts are overrun by martians. Unclear which are which.');
prefer_asserts_with_message
Assert'e mesaj eklemek, geliştiricinin AssertionError'ın neden oluştuğunu anlamasına yardımcı olur.
Yanlış kullanım:
f(a) {
assert(a != null);
}
class A {
A(a) : assert(a != null);
}
Doğru kullanım:
f(a) {
assert(a != null, 'a must not be null');
}
class A {
A(a) : assert(a != null, 'a must not be null');
}
prefer_collection_literals
Mümkün olduğunca koleksiyon literallerini kullanın.
Yanlış kullanım:
var points = List();
var addresses = Map();
var uniqueNames = Set();
var ids = LinkedHashSet();
var coordinates = LinkedHashMap();
Doğru kullanım:
var points = [];
var addresses = <String,String>{};
var uniqueNames = <String>{};
var ids = <int>{};
var coordinates = <int,int>{};
İSTİSNALAR:
LinkedHashSet veya LinkedHashMap ile, bir literal constructor'ın bir tür hatasını tetiklediği ve bu sebeple bunların lint'den hariç tutulduğu bazı durumlar vardır.
void main() {
LinkedHashSet<int> linkedHashSet = LinkedHashSet.from([1, 2, 3]); // OK
LinkedHashMap linkedHashMap = LinkedHashMap(); // OK
printSet(LinkedHashSet<int>()); // LINT
printHashSet(LinkedHashSet<int>()); // OK
printMap(LinkedHashMap<int, int>()); // LINT
printHashMap(LinkedHashMap<int, int>()); // OK
}
void printSet(Set<int> ids) => print('$ids!');
void printHashSet(LinkedHashSet<int> ids) => printSet(ids);
void printMap(Map map) => print('$map!');
void printHashMap(LinkedHashMap map) => printMap(map);
prefer_conditional_assignment
Null testi yerine ??= kullanmayı tercih edin.
??= >>>> ==null
Yanlış kullanım:
String get fullName {
if (_fullName == null) {
_fullName = getFullUserName(this);
}
return _fullName;
}
Doğru kullanım:
String get fullName {
return _fullName ??= getFullUserName(this);
}
prefer_const_constructors
Constant(sabit) constructor'larda const kullanın.
Yanlış kullanım:
class A {
const A();
}
void accessA() {
A a = new A();
}
Doğru kullanım:
class A {
const A();
}
void accessA() {
A a = const A();
}
Doğru kullanım:
class A {
final int x;
const A(this.x);
}
A foo(int x) => new A(x);
prefer_const_constructors_in_immutables
immutable sınıflarında const constructorları kullanın.
Yanlış kullanım:
@immutable
class A {
final a;
A(this.a);
}
Doğru kullanım:
@immutable
class A {
final a;
const A(this.a);
}
prefer_const_declarations
Const declaration'ları için const kullanın.
Yanlış kullanım:
final o = const <int>[];
class A {
static final o = const <int>[];
}
Doğru kullanım:
const o = <int>[];
class A {
static const o = <int>[];
}
prefer_const_literals_to_create_immutables
Immutable sınıflarında constructor paremetresi olarak literalleri kullanın.
Immutable sınıf örneklemelerinde (instantiating ) parametre olarak kullanılan list, map ve set literal'lerini başlatmak için const kullanmayı TERCİH edin.
- Not: Instantiate (fiil) ve instantiation (isim), nesne yönelimli programlama (OOP) dilinde bir nesnenin (veya belirli bir sınıfın "örneğinin") oluşturulmasına atıfta bulunur. *
Yanlış kullanım:
@immutable
class A {
A(this.v);
final v;
}
A a1 = new A([1]);
A a2 = new A({});
Doğru kullanım:
A a1 = new A(const [1]);
A a2 = new A(const {});
prefer_constructors_over_static_methods
Instanece'lar (örnekler) oluşturmak için statik methodlar yerine constructor tanımlamayı tercih edin.
Çoğu durumda, instantiation'ı daha net hale getirdiği için statik bir method yerine adlandırılmış bir constructor kullanmak daha mantıklıdır.
Yanlış kullanım:
class Point {
num x, y;
Point(this.x, this.y);
static Point polar(num theta, num radius) {
return Point(radius * math.cos(theta),
radius * math.sin(theta));
}
}
Doğru kullanım:
class Point {
num x, y;
Point(this.x, this.y);
Point.polar(num theta, num radius)
: x = radius * math.cos(theta),
y = radius * math.sin(theta);
}
prefer_contains
indexOf'u bir listenin bir öğeyi içerip içermediğini bulmak için kullanmayın.
Bunun yerine contains kullanın.
Yanlış kullanım:
if (lunchBox.indexOf('sandwich') == -1) return 'so hungry...';
Doğru kullanım:
if (!lunchBox.contains('sandwich')) return 'so hungry...';
prefer_equal_for_default_values
Adlandırılmış bir parametreyi varsayılan değerinden ayırmak için = kullanın.
Yanlış kullanım:
m({a: 1})
Doğru kullanım:
m({a = 1})
prefer_final_fields
Daha sonra kitaplıkta yeniden atanmamışlarsa, private alanları final olarak bildirmeyi tercih edin.
Alanları mümkün olduğunda final olarak bildirmek iyi bir uygulamadır bu kullanım durumu yanlışlıkla yeniden atamaları önlemeye yardımcı olur ve derleyicinin optimizasyon yapmasına izin verir.
Yanlış kullanım:
class BadImmutable {
var _label = 'hola mundo! BadImmutable'; // LINT
var label = 'hola mundo! BadImmutable'; // OK
}
Yanlış kullanım:
class MultipleMutable {
var _label = 'hola mundo! GoodMutable', _offender = 'mumble mumble!'; // LINT
var _someOther; // LINT
MultipleMutable() : _someOther = 5;
MultipleMutable(this._someOther);
void changeLabel() {
_label= 'hello world! GoodMutable';
}
}
Doğru kullanım:
class GoodImmutable {
final label = 'hola mundo! BadImmutable', bla = 5; // OK
final _label = 'hola mundo! BadImmutable', _bla = 5; // OK
}
Doğru kullanım:
class GoodMutable {
var _label = 'hola mundo! GoodMutable';
void changeLabel() {
_label = 'hello world! GoodMutable';
}
}
Yanlış kulanım:
class AssignedInAllConstructors {
var _label; // LINT
AssignedInAllConstructors(this._label);
AssignedInAllConstructors.withDefault() : _label = 'Hello';
}
Doğru kullanım:
class NotAssignedInAllConstructors {
var _label; // OK
NotAssignedInAllConstructors();
NotAssignedInAllConstructors.withDefault() : _label = 'Hello';
}
prefer_final_in_for_each
For-each döngüleri için değişkenleri final olarak bildirmek, yanlışlıkla yeniden atamaları önleyerek derleyicinin optimizasyon yapmasını sağlar.
Yanlış kullanım:
for (var element in elements) { // LINT
print('Element: $element');
}
Doğru kullanım:
for (final element in elements) {
print('Element: $element');
}
Doğru kullanım:
for (var element in elements) {
element = element + element;
print('Element: $element');
}
prefer_final_locals
Daha sonra yeni bir değer atanmayacaksa değişkenleri final olarak tanımlayın.
Yanlış kullanım:
void badMethod() {
var label = 'hola mundo! badMethod'; // LINT
print(label);
}
Doğru kullanım:
void goodMethod() {
final label = 'hola mundo! goodMethod';
print(label);
}
Doğru kullanım:
void mutableCase() {
var label = 'hola mundo! mutableCase';
print(label);
label = 'hello world';
print(label);
}
prefer_final_parameters
Yeniden değer atanmayacaksa parametre bildirimleri için final'ı tercih edin.
Yanlış kullanım:
void badParameter(String label) { // LINT
print(label);
}
Doğru kullanım:
void goodParameter(final String label) { // OK
print(label);
}
Yanlış kullanım: void badExpression(int value) => print(value); // LINT
Doğru kullanım: void goodExpression(final int value) => print(value); // OK
Yanlış kullanım:[1, 4, 6, 8].forEach((value) => print(value + 2)); // LINT
Doğru kullanım: [1, 4, 6, 8].forEach((final value) => print(value + 2)); // OK
Doğru kullanım:
void mutableParameter(String label) { // OK
print(label);
label = 'Hello Linter!';
print(label);
}
prefer_for_elements_to_map_fromIterable
Yanlış kullanım:
Map<String, WidgetBuilder>.fromIterable(
kAllGalleryDemos,
key: (demo) => '${demo.routeName}',
value: (demo) => demo.buildRoute,
);
Doğru kullanım:
return {
for (var demo in kAllGalleryDemos)
'${demo.routeName}': demo.buildRoute,
};
prefer_foreach
Tüm elementlere yalnızca bir fonksiyon uygulamak için forEach kullanın.
Bir iterable (yinelenebilir) öğenin tüm öğelerine yalnızca bir fonksiyon veya method uygulayacaksanız, forEach'i kullanın.
Yanlış kullanım:
for (final key in map.keys.toList()) {
map.remove(key);
}
Doğru kullanım:
map.keys.toList().forEach(map.remove);
for (myList'teki son v) {
foo().f(v); // Bu kod foo()'yu birçok kez çağırır.
}
myList.forEach(foo().f); // Ama bu kod, foo()'yu yalnızca bir kez çağırır.
prefer_function_declarations_over_variables
Bir fonksiyonu bir ada bağlamak için bir function declaration (fonksiyon bildirimi) kullanın.
Dart, local fonksiyon bildirimlerine (declarations) izin verdiğinden, bunları function literal'leri yerine kullanmak iyi bir uygulamadır.
Yanlış kullanım:
void main() {
var localFunction = () {
...
};
}
Doğru kullanım:
void main() {
localFunction() {
...
}
}
prefer_generic_function_type_aliases
Generic fonksiyonların tanıtılmasıyla birlikte, function type takma adları (typedef void F()), kullanıcıların ifade etmek isteyebileceği tüm olası parametreleştirme türlerini ifade edemedi. Generic function type takma adları (typedef F = void Function()) bu sorunu düzeltti.
Tutarlılık ve okunabilirlik nedenleriyle, yalnızca bir sözdizimi kullanmak ve dolayısıyla Generic function type takma adlarını (aliases) tercih etmek daha iyidir.
Yanlış kullanım: typedef void F();
Doğru kullanım: typedef F = void Function();
prefer_if_elements_to_conditional_expressions
Mümkünse if öğelerini koşullu ifadelere tercih (conditional expressions) edin.
Koleksiyonlar oluştururken, koşul öğelerinden ziyade if öğelerinin kullanılması tercih edilir.
Yanlış kullanım:
Widget build(BuildContext context) {
return Row(
children: [
IconButton(icon: Icon(Icons.menu)),
Expanded(child: title),
isAndroid ? IconButton(icon: Icon(Icons.search)) : null,
].where((child) => child != null).toList(),
);
}
Doğru kullanım:
Widget build(BuildContext context) {
return Row(
children: [
IconButton(icon: Icon(Icons.menu)),
Expanded(child: title),
if (isAndroid) IconButton(icon: Icon(Icons.search)),
]
);
}
prefer_if_null_operators
Koşullu ifadelerde null kontrolleri yerine if null operatörlerini kullanmayı tercih edin.
Yanlış kullanım: v = a == null ? b : a;
Doğru kullanım: v = a ?? b;
prefer_initializing_formals
Mümkün olduğunda initializing formal'lerini kullanmak, kodunuzu daha özlü hale getirir.
Yanlış kullanım:
class Point {
num x, y;
Point(num x, num y) {
this.x = x;
this.y = y;
}
}
Doğru kullanım:
class Point {
num x, y;
Point(this.x, this.y);
}
Yanlış kullanım:
class Point {
num x, y;
Point({num x, num y}) {
this.x = x;
this.y = y;
}
}
Doğru kullanım:
class Point {
num x, y;
Point({this.x, this.y});
}
NOT: Bu kural, parametre adı ve alan adı aynı olmadıkça, adlandırılmış parametreler için bir lint oluşturmaz. Bunun nedeni, böyle bir lint'i çözmenin ya alanı yeniden adlandırmayı ya da parametreyi yeniden adlandırmayı gerektireceği ve bu eylemlerin her ikisinin de potansiyel olarak bir kırılma değişikliği olacağıdır. Örneğin, aşağıdakiler bir lint oluşturmaz:
class Point {
bool isEnabled;
Point({bool enabled}) {
this.isEnabled = enabled; // OK
}
}
prefer_inlined_adds
Mümkün olduğunda add ve addAll methodlarını kullanmak yerine öğeleri liste literal'lerinde (değişmezlerinde) satır içi olarak bildirin.
Yanlış kullanım:
var l = ['a']..add('b')..add('c');
var l2 = ['a']..addAll(['b', 'c'])
Doğru kullanım:
var l = ['a', 'b', 'c'];
var 2 = ['a', 'b', 'c'];
prefer_int_literals
int literallerini double literallerine tercih edin.
Yanlış kullanım:
const double myDouble = 8.0;
final anotherDouble = myDouble + 7.0e2;
main() {
someMethod(6.0);
}
Doğru kullanım:
const double myDouble = 8;
final anotherDouble = myDouble + 700;
main() {
someMethod(6);
}
prefer_interpolation_to_compose_strings
Stringleri ve değerleri oluşturmak için enterpolasyonu kullanın.
Stringleri ve değerleri oluştururken enterpolasyonu kullanmak, genellikle birleştirmeden (concatenation) daha kolay yazılır ve okunur.
Yanlış kullanım: 'Hello, ' + name + '! You are ' + (year - birth) + ' years old.';
Doğru kullanım:'Hello, $name! You are ${year - birth} years old.';
prefer_is_empty
Iterable'lar ve map'ler için isEmpty kullanın.
Bir koleksiyonun boş olup olmadığını görmek için length kullanmayın.
Bunun yerine, daha hızlı ve daha okunabilir getter'lar vardır: isEmpty ve isNotEmpty.
Yanlış kullanım:
if (lunchBox.length == 0) return 'so hungry...';
if (words.length != 0) return words.join(' ');
Doğru kullanım:
if (lunchBox.isEmpty) return 'so hungry...';
if (words.isNotEmpty) return words.join(' ');
prefer_is_not_empty
Iterable'lar ve map'ler için isNotEmpty kullanın.
Iterable veya map'in boş olup olmadığını test ederken, kodun okunabilirliğini artırmak için !isEmpty yerine isNotEmpty'i tercih edin.
Yanlış kullanım:
if (!sources.isEmpty) {
process(sources);
}
Doğru kullanım:
if (todo.isNotEmpty) {
sendResults(request, todo.isEmpty);
}
prefer_is_not_operator
Bir nesnenin belirli bir tipte olup olmadığını kontrol ederken, 'is!' operatörünü kullanın.
Yanlış kullanım:
if (!(foo is Foo)) {
...
}
Doğru kullanım:
if (foo is! Foo) {
...
}
prefer_iterable_whereType
iterable (yinelenebilir) durumda whereType kullanmayı tercih edin.
iterable.where((e) => e is T) yerine iterable.whereType()'ı kullanın.
Yanlış kullanım: iterable.where((e) => e is MyClass)
Doğru kullanım: iterable.whereType<MyClass>()
prefer_mixin
Mixin'leri kullanın.
Karıştırılacak türler için her zaman mixin stili kullanılmalıdır.
Yanlış kullanım:
class A {}
class B extends Object with A {}
Doğru kullanım:
mixin M {}
class C with M {}
prefer_null_aware_method_calls
Bir foksiyon/method f'nin geçersizliğini(nullability), onu çağırmadan önce kontrol etmek yerine, f?.call() öğesini kullanabilirsiniz.
Yanlış kullanım:if (f != null) f!();
Doğru kullanım: f?.call();
prefer_null_aware_operators
Koşullu ifadelerde boş denetimler yerine null aware operator kullanmayı tercih edin.
Yanlış kullanım: v = a == null ? null : a.b;
Doğru kullanım: v = a?.b;
prefer_spread_collections
Mümkün olduğunda spread -yayılmış koleksiyonları kullanın.
Tek tek öğelerden yeni bir koleksiyon oluşturmak istediğinizde koleksiyon literal'leri mükemmeldir. Ancak, mevcut öğeler zaten başka bir koleksiyonda depolandığında, spread koleksiyon sözdizimi daha basit koda yol açar.
Yanlış kullanım:
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: ListView(
children: [
Tab2Header(),
]..addAll(buildTab2Conversation()),
),
);
}
var ints = [1, 2, 3];
print(['a']..addAll(ints.map((i) => i.toString()))..addAll(['c']));
var things;
var l = ['a']..addAll(things ?? const []);
Doğru kullanım:
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: ListView(
children: [
Tab2Header(),
...buildTab2Conversation(),
],
),
);
}
var ints = [1, 2, 3];
print(['a', ...ints.map((i) => i.toString()), 'c');
var things;
var l = ['a', ...?things];
prefer_typing_uninitialized_variables
Var ile tanımladığınız değişkenlere initial-başlangıç değeri atayın.
Bu kullanım değişkenlere başlangıçta amaçlamadığınız bir tür atamanızın önüne geçer.
Yanlış kullanım:
class BadClass {
static var bar; // LINT
var foo; // LINT
void method() {
var bar; // LINT
bar = 5;
print(bar);
}
}
Yanlış kullanım:
void aFunction() {
var bar; // LINT
bar = 5;
...
}
Doğru kullanım:
class GoodClass {
static var bar = 7;
var foo = 42;
int baz; // OK
void method() {
int baz;
var bar = 5;
...
}
}
public_member_api_docs
Yanlış kullanım:
class Bad {
void meh() { }
}
Doğru kullanım:
/// A good thing.
abstract class Good {
/// Start doing your thing.
void start() => _start();
_start();
}
İstisnai durum:
/// Base of all things.
abstract class Base {
/// Initialize the base.
void init();
}
/// A sub base.
class Sub extends Base {
@override
void init() { ... }
}
recursive_getters
Recursive (özyinelemeli) alıcılar oluşturmayın.
Recursive alıcılar, kendilerini bir değer olarak döndüren alıcılardır. Bu genellikle bir yazım hatasıdır.
Yanlış kullanım: int get field => field; // LINT
Yanlış kullanım:
int get otherField {
return otherField; // LINT
}
Doğru kullanım: int get field => _field;
sized_box_for_whitespace
Bir layout'a boşluk eklemek için SizedBox kullanın.
Yanlış kullanım:
Widget buildRow() {
return Row(
children: <Widget>[
const MyLogo(),
Container(width: 4),
const Expanded(
child: Text('...'),
),
],
);
}
Doğru kullanım:
Widget buildRow() {
return Row(
children: const <Widget>[
MyLogo(),
SizedBox(width: 4),
Expanded(
child: Text('...'),
),
],
);
}
size_box_shrink_expand
Yanlış kullanım:
Widget buildLogo() {
return SizedBox(
height: 0,
width: 0,
child: const MyLogo(),
);
}
Widget buildLogo() {
return SizedBox(
height: double.infinity,
width: double.infinity,
child: const MyLogo(),
);
}
Doğru kullanım:
Widget buildLogo() {
return SizedBox.shrink(
child: const MyLogo(),
);
}
Widget buildLogo() {
return SizedBox.expand(
child: const MyLogo(),
);
}
slash_for_doc_comments
Doküman yorumları için /// kullanmayı tercih edin.
Doğru kullanım:
/// Parses a set of option strings. For each option:
///
/// * If it is `null`, then it is ignored.
/// * If it is a string, then [validate] is called on it.
/// * If it is any other type, it is *not* validated.
void parse(List options) {
// ...
}
sort_child_properties_last
Widget örneği oluşturma işlemlerinde alt özellikleri en son sıralayın.
Yanlış kullanım:
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
mainAxisAlignment: MainAxisAlignment.center,
),
widthFactor: 0.5,
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: _incrementCounter,
tooltip: 'Increment',
),
);
Doğru kullanım:
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
widthFactor: 0.5,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
İstisna: Child özelliğinden sonra bir fonksiyon ifadesi içeren parametreye izin verilir.
sort_constructors_first
Constructor bildirimlerini (declarations) diğer üyelerden önce sıralayın.
Yanlış kullanım:
abstract class Visitor {
double value;
visitSomething(Something s);
Visitor();
}
Doğru kullanım:
abstract class Animation<T> {
const Animation(this.value);
double value;
void addListener(VoidCallback listener);
}
sort_unnamed_constructors_first
Önce adsız constructor bildirimlerini sıralayın.
Adsız constructor bildirimlerini, adlandırılmış olanlardan önce sıralayın.
Yanlış kullanım:
class _PriorityItem {
factory _PriorityItem.forName(bool isStatic, String name, _MemberKind kind) => ...
_PriorityItem(this.isStatic, this.kind, this.isPrivate);
...
}
Doğru kullanım:
abstract class CancelableFuture<T> implements Future<T> {
factory CancelableFuture(computation()) => ...
factory CancelableFuture.delayed(Duration duration, [computation()]) => ...
...
}
tighten_type_of_initializing_formals
Yanlış kullanım:
class A {
A.c1(this.p) : assert(p != null);
A.c2(this.p);
final String? p;
}
Doğru kullanım:
class A {
A.c1(String this.p) : assert(p != null);
A.c2(this.p);
final String? p;
}
type_init_formals
Bir alanı başlatmak için bir constructor parametresi kullanılıyorsa this.x, parametre türünün alanla aynı tür olduğu anlaşılır.
Yanlış kullanım:
class Point {
int x, y;
Point(int this.x, int this.y);
}
Doğru kullanım:
class Point {
int x, y;
Point(this.x, this.y);
}
unawated_futures
Future olarak tanımlanan methodları çağırırken await kullanmayı unutmayın.
Doğru kullanım:
Future doSomething() => ...;
void main() async {
await doSomething();
unawaited(doSomething()); // Explicitly-ignored fire-and-forget.
}
Yanlış kullanım:
void main() async {
doSomething(); // Likely a bug.
}
unnecessary_await_in_return
Gereksiz await anahtar kelimesi kullanmayın.
Yanlış kullanım:
Future<int> future;
Future<int> f1() async => await future;
Future<int> f2() async {
return await future;
}
Doğru kullanım:
Future<int> future;
Future<int> f1() => future;
Future<int> f2() {
return future;
}
unnecessary_brace_in_string_interps
Gerekmediği zaman enterpolasyonda parantez kullanmaktan kaçının.
Yanlış kullanım: print("Hi, ${name}!");
Doğru kullanım: print("Hi, $name!");
unnecessary_const
Bir const bağlamında const anahtar sözcüğünü yinelemekten kaçının.
Yanlış kullanım:
class A { const A(); }
m(){
const a = const A();
final b = const [const A()];
}
Doğru kullanım:
class A { const A(); }
m(){
const a = A();
final b = const [A()];
}
unnecessary_constructor_name
Gereksiz new kullanımından kaçının.
Yanlış kullanım:
class A {
A.new(); // LINT
}
var a = A.new(); // LINT
Doğru kullanım:
class A {
A.ok();
}
var a = A();
var aa = A.ok();
var makeA = A.new;
unnecessary_final
Local değişkenler için final kullanmayın.
var daha kısadır ve final kodun anlamını değiştirmez.
Yanlış kullanım:
void badMethod() {
final label = 'Final or var?';
for (final char in ['v', 'a', 'r']) {
print(char);
}
}
Doğru kullanım:
void goodMethod() {
var label = 'Final or var?';
for (var char in ['v', 'a', 'r']) {
print(char);
}
}
unnecessary_getters_setters
Alanları yalnızca güvenli olsunlar diye getter ve setter'lara sarmaktan kaçının.
Java ve C#'da, uygulama sadece field'a iletse bile, tüm alanları getter ve setter'ların (veya C#'daki propertilerin) arkasına gizlemek yaygındır. Bunun nedeni, bir getter method'u çağırmanın Java'da bir alana erişmekten farklı olması ve bir property'e (özelliğe) erişmenin, C#'ta raw field'a erişimle binary-compatible olmamasıdır.
Dart'ın bu sınırlaması yoktur. Field'lar ve getter/setter'lar tamamen ayırt edilemez. Bir sınıftaki bir field'ı açığa çıkarabilir ve daha sonra bu field'ı kullanan herhangi bir koda dokunmak zorunda kalmadan bir getter ve setter içine sarabilirsiniz.
Yanlış kullanım:
class Box {
var _contents;
get contents => _contents;
set contents(value) {
_contents = value;
}
}
Doğru kullanım:
class Box {
var contents;
}
unnecessary_lambdas
Tear-off işlemi yapılacaksa lambda kullanmayın.
Yanlış kullanım:
names.forEach((name) {
print(name);
});
Doğru kullanım: names.forEach(print);
unnecessary_late
Tanımlanırken değeri atanan değişkenlerde late kullanmayın.
Yanlış kullanım: late String badTopLevel = '';
Doğru kullanım: String goodTopLevel = '';
Yanlış kullanım:
class BadExample {
static late String badStatic = '';
}
Doğru kullanım:
class GoodExample {
late String goodStatic;
}
unnecessary_new
Örnek oluşturmak için gereksiz new kullanmaktan kaçının.
Yanlış kullanım:
class A { A(); }
m(){
final a = new A();
}
Doğru kullanım:
class A { A(); }
m(){
final a = A();
}
unnecessary_null_aware_assignments
Null-aware atamasında null kullanmaktan kaçının.
Yanlış kullanım:
var x;
x ??= null;
Doğru kullanım:
var x;
x ??= 1;
unnecessary_null_checks
Null yapılabilir bir değer kabul edildiğinde null kontrolü uygulamayın.
Yanlış kullanım:
f(int? i);
m() {
int? j;
f(j!);
}
Doğru kullanım:
f(int? i);
m() {
int? j;
f(j);
}
unnecessary_null_in_if_null_operators
if null operandlarında operatör olarak null kullanmaktan kaçının.
Bir if null operatöründe null kullanılması, null'ın hangi tarafta kullanıldığına bakılmaksızın gereksizdir.
Yanlış kullanım:
var x = a ?? null;
var y = null ?? 1;
Doğru kullanım:var x = a ?? 1;
unnecessary_raw_strings
Raw string'i yalnızca gerektiğinde kullanın.
Yanlış kullanım: var s1 = r'a';
Doğru kullanım:
var s1 = 'a';
var s2 = r'$a';
var s3 = r'\a';
unnecessary_string_escapes
String'lerdeki gereksiz ters eğik çizgileri kaldırın.
Yanlış kullanım:
'this string contains 2 \"double quotes\" ';
"this string contains 2 \'single quotes\' ";
Doğru kullanım:
'this string contains 2 "double quotes" ';
"this string contains 2 'single quotes' ";
unnecessary_string_interpolations
İçinde yalnızca bir string ifade varsa, string enterpolasyonu kullanmayın.
Yanlış kullanım:
String message;
String o = '$message';
Doğru kullanım:
String message;
String o = message;
unnecessary_this
Gerekmedikçe this kullanmayın.
Yanlış kullanım:
class Box {
var value;
void update(new_value) {
this.value = new_value;
}
}
Doğru kullanım:
class Box {
var value;
void update(new_value) {
value = new_value;
}
}
Doğru kullanım:
class Box {
var value;
void update(value) {
this.value = value;
}
}
use_decorated_box
Container'da yalnızca bir Dekorasyon olduğunda DecoratedBox kullanın.
Bir Container, DecoratedBox'tan daha ağır bir Widget'tır ve bonus olarak, DecoratedBox'ın bir const kurucusu vardır.
Yanlış kullanım:
Widget buildArea() {
return Container(
decoration: const BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(
Radius.circular(5),
),
),
child: const Text('...'),
);
}
Doğru kullanım:
Widget buildArea() {
return const DecoratedBox(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(
Radius.circular(5),
),
),
child: Text('...'),
);
}
use_full_hex_values_for_flutter_colors
Color'ı başlatmak için 8 basamaklı bir onaltılık tamsayı (0xFFFFFFFF) tercih edin.
Yanlış kullanım:
Color(1);
Color(0x000001);
Doğru kullanım: Color(0x00000001);
use_function_type_syntax_for_parameters
Paremetreler için generic function syntax'ını (söz dizimini) kullanın.
Yanlış kullanım: Iterable<T> where(bool predicate(T element)) {}
Doğru kullanım: Iterable<T> where(bool Function(T) predicate) {}
use_if_null_to_convert_nulls_to_bools
Null değerleri bool'a dönüştürmek için if-null operatörlerini kullanın.
Yanlış kullanım:
if (nullableBool == true) {
}
if (nullableBool != false) {
}
Doğru kullanım:
if (nullableBool ?? false) {
}
if (nullableBool ?? true) {
}
use_is_even_rather_than_modulo
% 2 sonucunu kontrol etmek yerine intValue.isOdd/isEven'i kullanmayı tercih edin.
Yanlış kullanım:
bool isEven = 1 % 2 == 0;
bool isOdd = 13 % 2 == 1;
Doğru kullanım:
bool isEven = 1.isEven;
bool isOdd = 13.isOdd;
use_late_for_private_fields_and_variables
Null yapılamayan private üyeler için late kullanın.
Bu kural şu anda deneyseldir.
Yanlış kullanım:
int? _i;
m() {
_i!.abs();
}
Doğru kullanım:
late int _i;
m() {
_i.abs();
}
use_named_constants
Mümkünse, önceden tanımlanmış const değerlerini kullanın.
Yanlış kullanım: const Duration(seconds: 0);
Doğru kullanım: Duration.zero;
use_raw_strings
Eğik çizgi \ ve dolar $ kullanmanız gerektiğinde raw string kullanın.
Yanlış kullanım: var s = 'A string with only \\ and \$';
Doğru kullanım: var s = r'A string with only \ and $';
use_rethrow_when_possible
Yakalanan bir istisnayı yeniden göndermek için rethrow kullanın.
Yanlış kullanım:
try {
somethingRisky();
} catch(e) {
if (!canHandle(e)) throw e;
handle(e);
}
Doğru kullanım:
try {
somethingRisky();
} catch(e) {
if (!canHandle(e)) rethrow;
handle(e);
}
use_setters_to_change_properties
Bir propertyi kavramsal olarak değiştiren işlemler için setter kullanın.
Yanlış kullanım:
rectangle.setWidth(3);
button.setVisible(false);
Doğru kullanım:
rectangle.width = 3;
button.visible = false;
use_string_buffers
Stringleri oluşturmak için string buffers kullanın.
Çoğu durumda, geliştirilmiş performansı nedeniyle stringleri oluşturmak için string buffer kullanılması tercih edilir.
Yanlış kullanım:
String foo() {
final buffer = '';
for (int i = 0; i < 10; i++) {
buffer += 'a'; // LINT
}
return buffer;
}
Doğru kullanım:
String foo() {
final buffer = StringBuffer();
for (int i = 0; i < 10; i++) {
buffer.write('a');
}
return buffer.toString();
}
use_test_throws_matchers
fail() ve try-catch yerine throwsA eşleştiricisini kullanın.
Yanlış kullanım:
// sync code
try {
someSyncFunctionThatThrows();
fail('expected Error');
} on Error catch (error) {
expect(error.message, contains('some message'));
}
// async code
try {
await someAsyncFunctionThatThrows();
fail('expected Error');
} on Error catch (error) {
expect(error.message, contains('some message'));
}
Doğru kullanım:
// sync code
expect(
() => someSyncFunctionThatThrows(),
throwsA(isA<Error>().having((Error error) => error.message, 'message', contains('some message'))),
);
// async code
await expectLater(
() => someAsyncFunctionThatThrows(),
throwsA(isA<Error>().having((Error error) => error.message, 'message', contains('some message'))),
);
use_to_and_as_if_applicable
Nesnenin durumunu yeni bir nesneye kopyalıyorsa, yöntemi to____() olarak adlandırmayı tercih edin.
Orijinal nesne tarafından desteklenen farklı bir temsil döndürüyorsa, yöntemi as___() olarak adlandırmayı tercih edin.
Yanlış kullanım:
class Bar {
Foo myMethod() {
return Foo.from(this);
}
}
Doğru kullanım:
class Bar {
Foo toFoo() {
return Foo.from(this);
}
}
Doğru kullanım:
class Bar {
Foo asFoo() {
return Foo.from(this);
}
}
References:
https://dart.dev/tools/linter-rules#style-rules
Posted on February 20, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.