함수를 정의할 때에는 main
함수 안에 있을 필요는 없다.
함수를 정의할 때 크게 두가지로 나뉘는데 return
을 할때와 안할때이다.
void sayHello(String name) {
print("Hello $name 만나서 반가워");
}
void main() {
//...
}
위와 같이 return
을 하지 않고 단순히 출력만 하는 함수의 경우에는 함수 이름 앞에 void
를 붙여서 만들어준다.
void
는 이 함수가 아무것도 return
하지 않는다는 의미이다.
그렇다면 main
함수 앞에 void
가 붙는 이유도 설명된다.
main
함수는 무언가를 return 하는 함수가 아니다.
단지 그 안에 들어있는 이벤트들을 실행해 줄 뿐이다.
무언가를 return 하기 위해서는 다음과 같이 return 할 데이터 타입을 명시해주어야 한다
String sayHello (String name) {
return "Hello $name 만나서 반가워";
}
void main() {
print(sayHello('yunu'));
// Hello yunu 만나서 반가워
}
그런데 위와 같이 별다른 명령 없이 바로 return
하는 함수의 경우에는
return
과 중괄호를 없애고 화살표 (=>
)를 이용해서 함수를 만들 수 있다.
fat arrow syntax (=>
)는 곧바로 return 한다는 의미다.
String sayHello (String name) => "Hello $name 만나서 반가워";
void main() {
print(sayHello('yunu'));
// Hello yunu 만나서 반가워
}
물론 이 방법은 곧바로 return 하는 경우에만 사용할 수 있다.
Dart에서는 다음과 같이 여러가지 데이터를 함수에 넣어서 만들 수 있다.
String sayHello (String name, int age, String country) {
return "Hello $name, you are $age, and you came from $country";
}
void main() {
print(sayHello('yunu', 23, "south Korea"));
// Hello yunu, you are 23, and you came from south Korea
}
하지만 sayHello('yunu', 23, "south Korea")
처럼 데이터들을 쭉 나열해서 사용하면
사용자가 순서를 헷갈릴 수도 있고, 처음 보는 사람은 이게 뭔가 싶을 수 있다.
이 때 named argument 를 사용해줄 수 있다.
named argument 를 사용할 때에는 다음과 같이 해준다.
String sayHello (String name, int age, String country)
String sayHello ({String name, int age, String country})
String sayHello (String name, int age, String country)
String sayHello ({String name = 'haha', int age = 20, String country = 'America'})
sayHello('yunu', 23, "south Korea")
sayHello(age: 23, country: 'South Korea', name: 'yunu')
<전체 코드>
String sayHello ({String name = 'haha', int age = 20, String country = 'America'}) {
return "Hello $name, you are $age, and you came from $country";
}
void main() {
print(sayHello(
age: 23,
country: 'South Korea',
name: 'yunu'
));
// Hello yunu, you are 23, and you came from South Korea
print(sayHello(
country: 'South Korea',
));
// Hello haha, you are 20, and you came from South Korea
// 데이터를 입력하지 않은 name과 age는 설정해둔 디폴트값으로 출력됨
}
만약 named argument를 사용하면서 디폴트값을 정해주고싶지 않다면 어떻게 해야할까?
즉, 값을 직접 사용자로부터 받아오고 싶다면?
이 때 required
를 사용할 수 있다.
사용법은 간단하다.
설정되어있던 디폴트값을 모두 지워주고 데이터 타입 앞에 required
만 붙여주면 된다.
required
를 사용할때는 함수를 쓸 때 데이터를 생략하는 것은 허용되지 않는다.
반드시 데이터에 값을 넣어서 함수를 사용하도록 한다.
Positional Parameters 는 함수를 사용할 때 참조값을 순서대로 넣어줘야한다는 의미이다.
String sayHello (String name, int age, String country) {
return "Hello $name, you are $age, and you came from $country";
}
void main() {
print(sayHello('nana', 12, 'japan'));
}
이런식으로 Positional Parameters 를 사용할 때에는 참조값이 하나라도 빠지면 에러가 뜬다.
하지만 optional 하게 Positional Parameters 를 사용하려면 다음과 같이 하면 된다.
함수를 만들 때 데이터를 대괄호로 묶어주고,
String country
→ [String country]
데이터타입 뒤에 물음표(?)를 붙여 nullable하게 만들어 준 다음,
[String country]
→ [String? country]
디폴트 값을 설정해준다.
[String? country]
→ [String? country = 'japan']
String sayHello (String name, int age, [String? country = 'japan']) =>
"Hello $name, you are $age, and you came from $country";
void main() {
var result = sayHello('nana', 12);
print(result);
// Hello nana, you are 12, and you came from japan
}
이렇게 하면 country
데이터를 입력하지 않아도 디폴트값인 ‘japan
’이 출력된다.
이름을 대문자로 바꿔서 return 하는 함수를 만들어보자
String capitalizeName(String name) => name.toUpperCase();
void main() {
capitalizeName('john');
}
이 함수에 null 값을 넣을 수 있게 해보자.
우선 String 뒤에 물음표를 붙여 nullable하게 만들어주고
null 값에는 toUpperCase 함수를 쓸 수 없으므로 조건문을 만들어준다.
String capitalizeName(String? name) {
if (name != null) {
return name.toUpperCase();
}
return 'NULL';
}
이걸 fat arrow(=>)를 이용해서 더 짧게 만들어주자.
String capitalizeName(String? name) => name != null ? name.toUpperCase() : 'NULL';
이걸 더 짧게 만들면?
여기서 QQ Operator 가 나온다.
QQ Operator
좌항 ?? 우항
좌항이 null 값일 경우 우항을 적용한다.
String capitalizeName(String? name) => name?.toUpperCase() ?? 'NULL';
name?.toUpperCase()
이 null
값일 경우 ‘NULL’
이라는 데이터를 반환할 것이다.
(name 뒤에 물음표는 name을 nullable 하게 만들기 위해 붙인 것이다.)
**QQ Equals (QQ Assignment Opertor)
데이터 ??= ‘값’;
데이터가 null 값일 경우 오른쪽 값을 넣어준다.
void main() {
String? name;
name ??= 'noon';
print(name);
// noon
}
name
이라는 데이터가 선언됐지만 null
값이므로 ‘noon
’이 name
에 할당된다.
List 의 요소 배열을 뒤집어서 return 하는 함수를 만들어보았다.
List<int> reverseListOfNumbers(List<int> list) {
var reversed = list.reversed;
return reversed.toList();
}
보면 List<int>
라는 코드가 여러번 쓰인다.
이를 typedef
를 이용해 변수에 담아서 다음처럼 List<int>
대신 사용할 수 있다..
typedef ListOfInts = List<int>;
ListOfInts reverseListOfNumbers(ListOfInts list) {
var reversed = list.reversed;
return reversed.toList();
}
물론 Map
의 경우에도 typedef
를 이용할 수 있지만
Map
처럼 구조화된 데이터의 경우에는 class
를 이용하는 것이 더 적절하다.
Class
는 다음 게시글에서 다룬다.
<참조>