티스토리 뷰

Development/Flutter

Dart Coding Style

오틸라 2023. 6. 1. 11:32
반응형

안녕하세요. 오틸라 입니다.

20년전 코딩하던 습관으로 flutter를 작업하다보면, 계속 알림이 붙습니다.

lowerCamelCase를 사용하지 않았다느니... 불필요하다느니....

 

프로그램상에 문제도 없고, 성능상에 문제도 없지만...자꾸뜨는 저 알림을 보면 은근히 신경쓰일때가 있습니다.

 

그래서 Dart에서 표준으로 정하고 있는 Coding Style 규칙을 공식홈페이지에서 발췌해 왔습니다.

 

 

Dart Coding Style

 

좋은 코드의 놀랍도록 중요한 부분은 좋은 스타일입니다. 일관된 이름 지정, 순서 지정 및 서식 지정은 동일한 코드  동일하게 보이도록 도와줍니다. 그것은 우리 대부분이 안구 시스템에 가지고 있는 강력한 패턴 일치 하드웨어를 활용합니다. 전체 Dart 생태계에서 일관된 스타일을 사용하면 우리 모두가 서로의 코드에서 더 쉽게 배우고 기여할 수 있습니다.

식별자

식별자는 Dart에서 세 가지 종류가 있습니다.

  • UpperCamelCase이름은 첫 글자를 포함하여 각 단어의 첫 글자를 대문자로 합니다.
  • lowerCamelCase이름은 각 단어의 첫 글자를 대문자로 표시합니다. 첫 번째 글자는 두문자어일지라도 항상 소문자로 표시됩니다 .
  • lowercase_with_underscores이름은 약어에도 소문자만 사용하고 _.

다음을 사용하여 이름 유형 지정UpperCamelCase

린터 규칙: camel_case_types

클래스, enum 유형, typedef 및 유형 매개변수는 각 단어(첫 단어 포함)의 첫 문자를 대문자로 표시하고 구분 기호를 사용하지 않아야 합니다.

class SliderMenu { ... }

class HttpRequest { ... }

typedef Predicate<T> = bool Function(T value);

여기에는 메타데이터 주석에 사용되는 클래스도 포함됩니다.

class Foo {
  const Foo([Object? arg]);
}

@Foo(anArg)
class A { ... }

@Foo()
class B { ... }

주석 클래스의 생성자가 매개변수를 사용하지 않는 경우 별도의 상수를 생성할 수 있습니다 lowerCamelCase.

const foo = Foo();

@foo
class C { ... }

DO 이름 확장자는 다음을 사용합니다.UpperCamelCase

린터 규칙: camel_case_extensions

유형과 마찬가지로 확장은 각 단어(첫 단어 포함)의 첫 글자를 대문자로 표시하고 구분 기호를 사용하지 않아야 합니다.

extension MyFancyList<T> on List<T> { ... }

extension SmartIterable<T> on Iterable<T> { ... }

 

다음을 사용하여 패키지, 디렉토리 및 소스 파일의 이름을 지정하십시오.lowercase_with_underscores

린터 규칙: file_names , package_names

일부 파일 시스템은 대소문자를 구분하지 않으므로 많은 프로젝트에서 파일 이름을 모두 소문자로 지정해야 합니다. 구분 문자를 사용하면 해당 형식으로 이름을 읽을 수 있습니다. 밑줄을 구분 기호로 사용하면 이름이 여전히 유효한 Dart 식별자임을 확인할 수 있습니다. 이는 언어가 나중에 기호 가져오기를 지원하는 경우 유용할 수 있습니다.

my_package
└─ lib
   └─ file_system.dart
   └─ slider_menu.dart
mypackage
└─ lib
   └─ file-system.dart
   └─ SliderMenu.dart

DO 이름 가져오기 접두사 사용lowercase_with_underscores

린터 규칙: library_prefixes

import 'dart:math' as math;
import 'package:angular_components/angular_components.dart' as angular_components;
import 'package:js/js.dart' as js;
import 'dart:math' as Math;
import 'package:angular_components/angular_components.dart' as angularComponents;
import 'package:js/js.dart' as JS;

다음을 사용하여 다른 식별자의 이름을 지정하십시오.lowerCamelCase

린터 규칙: non_constant_identifier_names

클래스 멤버, 최상위 정의, 변수, 매개변수 및 명명된 매개변수는 첫 단어를 제외한 각 단어의 첫 글자를 대문자로 표시하고 구분 기호를 사용하지 않아야 합니다.

var count = 3;

HttpRequest httpRequest;

void align(bool clearItems) {
  // ...
}

lowerCamelCase상수 이름에 사용하는 것이 좋습니다.

린터 규칙: constant_identifier_names

새 코드에서는 lowerCamelCase열거형 값을 포함한 상수 변수에 사용합니다.

const pi = 3.14;
const defaultTimeout = 1000;
final urlScheme = RegExp('^([a-z]+):');

class Dice {
  static final numberGenerator = Random();
}
const PI = 3.14;
const DefaultTimeout = 1000;
final URL_SCHEME = RegExp('^([a-z]+):');

class Dice {
  static final NUMBER_GENERATOR = Random();
}

SCREAMING_CAPS다음과 같은 경우와 같이 기존 코드와의 일관성을 위해 사용할 수 있습니다 .

  • 이미 SCREAMING_CAPS.
  • 예를 들어 protobufs에서 생성된 열거 유형에서 Java 코드와 병렬인 Dart 코드를 생성할 때 .

 참고:SCREAMING_CAPS 처음에는 상수에 Java 스타일을 사용했습니다 . 다음과 같은 몇 가지 이유로 변경했습니다.

  • SCREAMING_CAPS많은 경우, 특히 CSS 색상과 같은 항목에 대한 enum 값이 좋지 않습니다.
  • 상수는 종종 이름 변경이 필요한 최종 비 상수 변수로 변경됩니다.
  • valuesenum 유형에서 자동으로 정의되는 속성은 const 및 소문자입니다 .

단어와 같이 두 글자보다 긴 두문자어 및 약어를 대문자로 사용하십시오.

대문자로 된 두문자어는 읽기 어려울 수 있으며 인접한 두문자어가 여러 개 있으면 이름이 모호해질 수 있습니다. 예를 들어 로 시작하는 이름이 주어지면 HTTPSFTPHTTPS FTP 또는 HTTP SFTP를 참조하는지 알 수 있는 방법이 없습니다.

이를 방지하기 위해 두문자어와 약어는 일반 단어처럼 대문자로 표시됩니다.

예외: IO(입력/출력)와 같은 두 글자 약어는IO 모두 대문자로 표시됩니다: . 반면에 ID(식별)와 같은 두 글자로 된 약어는 여전히 일반 단어처럼 대문자로 표시됩니다: Id.

class HttpConnection {}
class DBIOPort {}
class TVVcr {}
class MrRogers {}

var httpRequest = ...
var uiHandler = ...
var userId = ...
Id id;
class HTTPConnection {}
class DbIoPort {}
class TvVcr {}
class MRRogers {}

var hTTPRequest = ...
var uIHandler = ...
var userID = ...
ID iD;

사용하지 않는 콜백 매개변수에 대해 , 등을 _사용 하는 것을 선호합니다.__

경우에 따라 콜백 함수의 형식 서명에 매개 변수가 필요하지만 콜백 구현에서는 매개 변수를 사용 하지 않습니다. 이 경우 사용하지 않는 매개변수의 이름을 지정하는 것이 관용적입니다 _. 함수에 사용되지 않은 매개변수가 여러 개 있는 경우 추가 밑줄을 사용하여 이름 충돌을 방지합니다( __, ___등).

futureOfVoid.then((_) {
  print('Operation complete.');
});

이 가이드라인은 익명이면서 로컬 인 기능에만 적용됩니다 . 이러한 함수는 일반적으로 사용되지 않은 매개변수가 무엇을 나타내는지 명확한 컨텍스트에서 즉시 사용됩니다. 반대로 최상위 함수 및 메서드 선언에는 해당 컨텍스트가 없으므로 각 매개 변수가 사용되지 않더라도 각 매개 변수의 용도가 명확하도록 매개 변수 이름을 지정해야 합니다.

비공개가 아닌 식별자에 선행 밑줄을 사용하지 마세요.

Dart는 식별자에 선행 밑줄을 사용하여 멤버 및 최상위 선언을 비공개로 표시합니다. 이렇게 하면 선행 밑줄을 이러한 종류의 선언 중 하나와 연결하도록 사용자를 교육할 수 있습니다. 그들은 "_"를 보고 "비공개"라고 생각합니다.

지역 변수, 매개변수, 지역 함수 또는 라이브러리 접두사에 대한 "비공개" 개념이 없습니다. 그 중 하나에 밑줄로 시작하는 이름이 있으면 독자에게 혼란스러운 신호를 보냅니다. 이를 방지하려면 해당 이름에 선행 밑줄을 사용하지 마십시오.

접두사를 사용하지 마십시오

헝가리어 표기법 및 기타 체계는 컴파일러가 코드를 이해하는 데 많은 도움을 주지 않았던 BCPL 시대에 등장했습니다. Dart는 선언의 유형, 범위, 가변성 및 기타 속성을 알려줄 수 있으므로 이러한 속성을 식별자 이름으로 인코딩할 이유가 없습니다.

defaultTimeout
kDefaultTimeout

라이브러리 이름을 명시적으로 지정하지 마세요.

지시문 에 이름을 추가하는 library것은 기술적으로 가능하지만 레거시 기능이므로 권장되지 않습니다.

Dart는 경로와 파일 이름을 기반으로 각 라이브러리에 대해 고유한 태그를 생성합니다. 명명 라이브러리는 이 생성된 URI를 재정의합니다. URI가 없으면 도구가 문제의 기본 라이브러리 파일을 찾기가 더 어려울 수 있습니다.

library my_library;
/// A really great test library.
@TestOn('browser')
library;

주문하기

파일의 서문을 깔끔하게 유지하기 위해 지시문이 나타나야 하는 규정된 순서가 있습니다. 각 "섹션"은 빈 줄로 구분되어야 합니다.

단일 linter 규칙이 모든 주문 지침인 directives_ordering을 처리합니다.

dart:다른 수입품보다 먼저 수입품을 배치하십시오.

린터 규칙: directives_ordering

import 'dart:async';
import 'dart:html';

import 'package:bar/bar.dart';
import 'package:foo/foo.dart';

package:상대적 가져오기 전에 가져오기를 배치하십시오.

린터 규칙: directives_ordering

import 'package:bar/bar.dart';
import 'package:foo/foo.dart';

import 'util.dart';

모든 가져오기 후에 별도의 섹션에서 내보내기를 지정하십시오.

린터 규칙: directives_ordering

import 'src/error.dart';
import 'src/foo_bar.dart';

export 'src/error.dart';
import 'src/error.dart';
export 'src/error.dart';
import 'src/foo_bar.dart';

섹션을 사전순으로 정렬하십시오.

린터 규칙: directives_ordering

import 'package:bar/bar.dart';
import 'package:foo/foo.dart';

import 'foo.dart';
import 'foo/foo.dart';
import 'package:foo/foo.dart';
import 'package:bar/bar.dart';

import 'foo/foo.dart';
import 'foo.dart';

 

 

반응형

 

포맷팅

많은 언어와 마찬가지로 Dart는 공백을 무시합니다. 그러나 인간은 그렇지 않습니다. 일관된 공백 스타일을 사용하면 독자가 컴파일러와 동일한 방식으로 코드를 볼 수 있습니다.

다음을 사용하여 코드를 포맷하십시오.dart format

서식 지정은 지루한 작업이며 리팩토링 중에 특히 시간이 많이 걸립니다. 다행히 걱정할 필요가 없습니다. 우리는 당신을 위해 그것을 수행하는 정교한 자동 코드 포맷터를 제공합니다 dart format. 적용되는 규칙에 대한 문서가 있지만 Dart의 공식 공백 처리 규칙 dart format은 .

나머지 서식 지침은 dart format수정할 수 없는 몇 가지 사항에 대한 것입니다.

보다 포맷터 친화적으로 코드를 변경하는 것을 고려하십시오.

포맷터는 어떤 코드를 사용하든 최선을 다하지만 기적을 일으킬 수는 없습니다. 코드에 특히 긴 식별자, 깊게 중첩된 표현식, 여러 종류의 연산자가 혼합된 경우 형식이 지정된 출력을 읽기 어려울 수 있습니다.

그런 일이 발생하면 코드를 재구성하거나 단순화하십시오. 지역 변수 이름을 줄이거나 식을 새 지역 변수로 호이스팅하는 것을 고려하십시오. 즉, 손으로 코드 서식을 지정하고 더 읽기 쉽게 만들려는 경우와 동일한 종류의 수정을 수행합니다. dart format때로는 반복적으로 함께 작업하여 아름다운 코드를 생성하는 파트너십으로 생각하십시오 .

80자보다 긴 줄을 피하십시오

린터 규칙: lines_longer_than_80_chars

가독성 연구에 따르면 긴 줄의 텍스트는 다음 줄의 시작 부분으로 이동할 때 눈이 더 멀리 이동해야 하기 때문에 읽기가 더 어렵습니다. 이것이 신문과 잡지가 여러 열의 텍스트를 사용하는 이유입니다.

실제로 80자보다 긴 줄을 원하는 경우 코드가 너무 장황하고 조금 더 간결할 수 있습니다. 주범은 보통 VeryLongCamelCaseClassNames. "해당 유형 이름의 각 단어가 나에게 중요한 것을 말하거나 이름 충돌을 방지합니까?"라고 스스로에게 물어보십시오. 그렇지 않은 경우 생략하는 것이 좋습니다.

이 작업의 99%는 귀하를 위해 수행 되지만 dart format마지막 1%는 귀하입니다. 80열에 맞게 긴 문자열 리터럴을 분할하지 않으므로 수동으로 분할해야 합니다.

예외: URI 또는 ​​파일 경로가 주석이나 문자열(일반적으로 가져오기 또는 내보내기)에서 발생하는 경우 줄이 80자를 초과하더라도 전체로 남을 수 있습니다. 이렇게 하면 경로에 대한 소스 파일을 더 쉽게 검색할 수 있습니다.

예외: 여러 줄 문자열은 줄 바꿈이 문자열 내에서 중요하고 줄을 더 짧은 줄로 분할하면 프로그램을 변경할 수 있기 때문에 80자보다 긴 줄을 포함할 수 있습니다.

모든 흐름 제어 문에 중괄호를 사용하십시오.

린터 규칙: curly_braces_in_flow_control_structures

이렇게 하면 매달려 있는 다른 문제를 피할 수 있습니다.

if (isWeekDay) {
  print('Bike to work!');
} else {
  print('Go dancing or read a book!');
}

예외:if 절이 없는 명령문이 else있고 전체 명령문이 한 줄에 들어갈 경우 if원하는 경우 중괄호를 생략할 수 있습니다.

if (arg == null) return defaultValue;

본문이 다음 줄로 넘어가면 중괄호를 사용하세요.

if (overflowChars != other.overflowChars) {
  return overflowChars < other.overflowChars;
}
if (overflowChars != other.overflowChars)
  return overflowChars < other.overflowChars;

 

 

 

 

 

이상 오틸라였습니다.

건강하세요~

반응형
댓글