frontend/mobile

[dart] functions

김포레스트 2023. 9. 25. 10:52

1. defingina function

  function 은 js 랑 달리 앞에 void 를 붙여 줘야 한다. 

void sayHello() {
  print("Hello World!!!!");
}

  이런식이다. 

  그런데, 만약!!!!! 저 print 되는 내용을 return 하고 싶다. 라고 하면 다음과 같이 바꾸어 주어야 한다.

void main() {
  print(sayHello());
}

String sayHello() {
  return "Hello World!!!!";
}

return 하고싶은 내용이 문자열이기 때문에 void가  String으로 바뀌었다.

만약 return 하고 싶은 내용이 숫자이면 int나 num이 될것이고,

객체이면 Object 가 되겠지?????

 

자료형에 비교적 자유로운 편이었던 js를 쓰다가 dart를 배우려니 조금 번거롭게 느껴지는 부분이 생긴다.

 

그리고 위의 함수를 조금 더 간략하게 표현하기 위해서 arrow function을 사용할 수도 있다,

void main() {
  print(sayHello());
}

String sayHello() => "Hello World!!!!";

중괄호도 사라졌고, return도 사라졌다.

근데, 이건 그냥 return되는 내용이 간략하니까 사용할 수 있는 것이고...

 

연산이나 데이터 정리 등등이 필요할 때는 어쩔 수 없이 중괄호 써야 할듯..

그리고 뭔가 그냥 보기 싫다. 함수 내용물은 중괄호로 예쁘게 포장해줘야 제 맛 아닐까..?

컵없이 물만 덩그러니 흐르는 느낌............흥..😒

 

 

 

2. parameter

  function 을 사용할 때, 파라미터를 사용할 수 있다. 그런데 js 와의 차이점이 있다.

  js 에서는 파라미터를 지정을 해놓고, 실행문에서 파라미터 없이 사용해도 오류가 발생하지 않았다.

  하지만 dart에서는 파라미터를 지정했다면, 꼭 그 값을 지정한 자료형에 맞추어 넣어 주어야 한다.

  값이 없어도 안되고, 자료형이 달라서도 안된다.

 

void main() {
  print(sayHello('Forest', 300, 'Developer'));
}

String sayHello(String name, int age, String job) {
  return "Hello World!!!! I'm $name, $age year old, and my job is $job";
}

  이렇게 사용 해야만 하는 것이다.

  그런데, 문제가 있다. 지금이야 파라미터가 세개 이니까 문제가 없지만..........(사실 그래도 문제이긴 함)

  실행문에 입력된 파라미터를 보았을 때, 쟤가 도대체 무슨 의미의 변수 인지를 알 수가 없다는 것이다.

  예를 들면, 저 300이라는 파라미터 값이 원래 age의 의미로 선언 되었던건지 가지고 있는 돈의 단위로 선언되었던 것인지 실행문만 보아서는 알 수 없다. 

 

  2-1. parameter 를 객체로 사용해보자. 

    그래서 실행문에서 파라미터를 사용 할 때에도, key값을 지정해주면 된다. 다음과 같이.

   

void main() {
  print(sayHello(
    name :'Forest', 
    age: 300, 
    job: 'Developer',
  ));
}

String sayHello({String name, int age, String job}) {
  return "Hello World!!!! I'm $name, $age year old, and my job is $job";
}

  함수 선언문 -> 파라미터부분에 중괄호를 추가함.

  함수 실행문 -> 파라미터 부분을 객체형식으로 수정함.

 

  그러나 이렇게 작성하면 오류가 발생하는데..!!!!

  바로, null safty 때문이다. 

 

  "네가 만든 파라미터.. 만약에 null값이면 어뜨케....?😥😥😥😥😥😥😥"

  라는 것이다. 

  뭐 null 일 수도 있지............. 라고 우리는 생각하지만 기계 입장에서는 조금 당황스러운가보지..? 

 

  어쨌든 얘를 해결 하려면 다음과 같은 방법을 사용하면 된다. 

   

   첫번째, 디폴트 값 넣기

void main() {
  print(sayHello(
    name :'Forest', 
    age: 300, 
    job: 'Developer',
  ));
}

String sayHello({String name = 'name', int age = 5000, String job = 'job'}) {
  return "Hello World!!!! I'm $name, $age year old, and my job is $job";
}

  파라미터를 선언할 때, 초기값을 지정해준다.

  그러면 어쨌든 null 값은 아니니까.

  대신 실제적으로 null 값이 들어갈 때, null 대신 세팅되었던 초기값이 출력된다.

 

 

   두번째, required 넣기

void main() {
  print(sayHello(
    name :'Forest', 
    age: 300, 
    job: 'Developer',
  ));
}

String sayHello({
  required String name, 
  required int age, 
  required String job, 
}) {
  return "Hello World!!!! I'm $name, $age year old, and my job is $job";
}

  파라미터를 선언할 때, 머리에 required를 넣어주면 된다. 

  required는 함수를 실행시키는 단계에서 null 값이 아닌 값이 포함되어있어야만 함수를 실행시켜준다.

  null 값이 들어가있으면 바로 오류를 뱉어낸다.

 

요렇게 말이다.

 

근데 위 두가지 방법은 모두 null 값을 허용하지 않는 방식이다. 

초기값을 설정해주거나, 실행단계 이전까지만 null 값을 허용 하기 때문에 지인짜로 null 값을 허용해 줘야하는 상황에서는 유용하지 않다. 

 

세번째, Optional Positional 파라미터 사용하기

  ? 뒤에 파라미터를 선언해서 null 값이더라도 실행해달라고 dart에게 졸라보면 된다.

void main() {
  print(sayHello('Forest', 300));
}

String sayHello(
  String name, 
  int age, 
  [String? job] 
) {
  return "Hello World!!!! I'm $name, $age year old, and my job is $job";
}

이때 출력은 다음과 같다. 

아......null 이라는 글자가 그대로 출력된다. 조금 환장스럽다.

대강 '' 과 같은 빈값을 넣어주는게 나을 수도 있겠다는 생각이 든다. 

 

네번째, QQ Operator 사용하기

물음표가 하나일 때도 있지만 두개를 사용할 때도 있는데, 그게 바로...... QQ Operator 이다.

간략히 설명하면,  null 값인지 확인해서 null 이 아닐 경우 ?? 의 왼쪽 값을, null 인경우 ?? 의 오른쪽 값을 리턴해주는 오퍼레이터다.

(null 아닐 때 리턴) ?? (null 일 때 리턴)

 

void main() {
  print(sayHello('Forest'));
  
  print(sayHello(null));
}

String sayHello(String? name) {
  if (name != null) {
    return $name;
  }
  return 'noName';
}

원래는 이렇게 if문으로 해결했어야 할 구문을 ??으로 간략하게 처리가 가능한 것이다.

 

 

void main() {
  print(sayHello('Forest'));
  
  print(sayHello(null));
}

String sayHello(String? name) => name ?? "NONE";

이러면 아래와 같이 출력된다.

 

근데 이렇게 하면 경고 뜸

이유는 다음과 같다.

String sayHello(String? name) => "I am $name" ?? "NONE"; 

 

?? 의 왼쪽이 null값이어야만 리턴이 되는데 저기에 문자열을 넣어버리면 null 값이 아니게 되기 때문...!!!!!!!!!!

복잡하다 복잡해

 

그럴 때에는 ??= 를 쓰면 된다.

void main() {
  print(sayHello('Forest'));
  
  print(sayHello(null));
}

String sayHello(String? name) {
  name ??= 'NoName';
  
  return "Hello, I am $name";
}

출력 내용은 다음과 같다

씁.... 내가 생각했던 내용에서 조그음씩 벗어났다. 

 

뭐 어쨌든.....

상황따라 잘 골라쓰면 될 듯.

 

 

끗-