본문 바로가기



Dart 15. 함수와 제어문 {유목민 알폰스}



dart에서 함수를 생성 후 getter,  setter를 통 안 입출력 및 기타 연산자를 알아보겠습니다.  

  1. 함수 선언하고 호출하기
  2. 매개변수의 사용
  3. 옵셔널 위치 매개변수
  4. 함수 타입 인수
  5. getter setter 함수
  6. 연산자의 활용
  7. 실행 흐름의 제어

1. 함수 선언과 호출

//톱레벨 함수
void fun1(){
}

//톱레벨함수 안에 함수
void fun2(){
	void fun2_1(){
    }
    fun2_1();
}

//클래스 안에 함수
class TestClass{
	void getTest(){
    }
}

 

함수의 중복 오버로딩을 지원하지 않습니다.

  • 오버로딩을 대신할 옵셔널 매개변수라는 기능이 있기 때문에 굳이 오버로딩을 지원하지 않아도 되는 것입니다.

 

  • 매개변수의 타입은 명시하거나 모든타입을 받을 수 있는 var타입을 선언하거나 또는 아예 생략할 수도 있습니다.
void fun1(int? a){//타입을 선언한 경우
}

void fun2(var a){//범용적인 타입 var로 선언한 경우
}

void fun(a){//타입을 생략한 경우
}

main(){
	//타입이 선언된 경우
    fun1(10);
    fun1(null);
    fun1('test');//<------에러
    
    //var로 선언된 경우
    fun2();//<------값을 전달하지 않으면 에러
    fun2(10);
    fun2('test');
    
    //타입을 생략한 경우 
    fun();//<------값을 전달하지 않으면 에러
    fun(10);
    fun('test');    
}

 

  • 반환타입이 없으면 void로 지정하고 반환타입이 있으면 반환할 타입이 함수명 앞에 붙습니다.
void fun1(){
}

String fun2(){
	return "hello";
}

int fun2(){
	return 5;
}

/*
fun3, fun4, fun5는 모두 리턴타입이 다이나믹(dynamic)타입이다. 
fun5의 경우는 null을 반환한다.
*/
dynamic fun3(){
	return 10;
}
fun4(){
	return 10;
}
fun5(){
}

 

  • 화살표 함수 사용
void fun1(){
	print('hello');
}

void fun2() => print('hello2');


main(){
	print(fun1());
	print(fun2());
}

결과)
hello
hello2

 

 

2. 매개변수의 사용

일반적인 매개변수 사용

void fun(int arg1, String arg2, bool argc){
}

main(){
	fun(); //에러
    fun('hello', true, 5); //에러
    fun(10, 'hello', true); //(성공)순서에 맞게 정확하게 입력해야 됨
}

 

명명된 매개변수 사용

  • 명명된 매개변수는 함수의 맨 마지막에 와야 합니다.
  • 명명된 매개변수는 2번 이상 선언할수 없습니다. 1번만 선언이 가능합니다.
  • 일반매개변수는 반드시 넘겨줘야하고 {} 매개변수는 하나도 안 넘겨줘도 되고 선택적으로 이름을 지정해서 넘겨줘도 되고 당연히 전체를 다 넘길 수도 있습니다.
  • 미리 fun({String nmae="아이유"}}; 이런식으로 디폴트값을 줄수도 있습니다.
  • 값을 자유롭게 안주도 되지만 필수값을 지정할 수도 있습니다. fun({required int num}{} 이렇게 required옵션이 붙은 매개변수는 반드시 넘겨줘야 합니다.
void f1({String? a1, bool? a2}, int a3){} //<---- 에러
void f2(int num, {String? a1, bool? a2}, {String? aa, bool? bb}){} //<---- 에러

void f3(int a, {String? a1, bool? a2}){} //<---- 성공

//호출시
f3(5, a1:3);
f3(5, a2:3);
f3(5, a1:1, a2:2);

 

 

3. 옵셔널 위치 매개변수

  • 자유롭게 생략가능 하지만 순서는 맞춰야 합니다.
void fun([String nm="홍길동", int age=10]){
}

fun("홍길동");//<------정상
fun("홍길동", 30);//<------정상
fun(30);//<------에러
fun(30, '홍길동');//<------에러

 

4. 함수 타입 인수

void fun1(){
  print('hello');
}

main(){
  Function varFun = fun1;
  varFun();
}

//---------------------------------------------------

int plusFun(int n1, int n2){
  return n1 + n2;
}

int multFun(int n1, int n2){
  return n1 * n2;
}

Function getFun(Function prmFun){
  print('prmFun : ${prmFun}');
  return multFun;
}

main(){
  Function varFun = getFun(plusFun);
  print('varFun : ${varFun(20, 3)}');
}

결과 ) 
prmFun : Closure: (int, int) => int from: function plusFun(n1, n2) {
    return n1 + n2;
  }
varFun : 60


//---------------------------------------------------

int plusFun(int n1, int n2){
  return n1 + n2;
}

int multFun(int n1, int n2){
  return n1 * n2;
}

Function getFun(Function prmFun){
  print('prmFun : ${prmFun(20, 10)}');
  return multFun;
}

main(){
  Function varFun = getFun(plusFun);
  print('varFun : ${varFun(20, 3)}');
}

결과) 
prmFun : 30
varFun : 60

 

함수타입 제한

  • some함수는 타입을 int f(int a) 라고 선언했기 때문에 숫자매개변수를 받고 숫자를 리턴하는 함수만 받을 수 있습니다.
some(int f(int a)){
	f(30);
}

main(List<String> args){
    same(
        (int a){
            return a + 20;
        }
    );
}

 

익명함수

  • some함수는 일반함수이고 some2라는 함수형 변수에는 이름이 없는 익명함수를 대입하고 있습니다.
some(arg){
	return 10;
}

Function some2 = (arg){
	return 10;
}
  • 함수타입 매개변수의 사용예
main(List<String> args){
    // 함수 타입 매개변수 사용 예
    var rs = ["사과", "배", "땅콩"];
    rs.forEach((item){
      print('${rs.indexOf(item)}:$item');
    });
}

 

  • forEach() 함수 정의
main(List<String> args){
    // 함수 타입 매개변수 사용 예
    var rs = ["사과", "배", "땅콩"];
    rs.forEach((item){
      print('${rs.indexOf(item)}:$item');
    });
}

 

5. getter setter함수

String _name = 'Hello';//프라이빗

String get name{//리턴전용
    return _name.toString();
}
set name(value){//입력전용
    _name = value;
}

main(List<String> args){
    name = "알폰스";//입력하고
    print('name:${name}');//출력하고
}

결과)
name:알폰스

6. 연산자의 활용

main(List<String> args){
    int a = 8;
    print('a/5 = ${a/5}');//실수로 반환
    print('a~/5 = ${a~/5}');//소숫점 아래 버림
}
결과)
a/5 = 1.6
a~/5 = 1

 

  • 타입 확인과 캐스팅 - Object형태로 대입은 했지만 User타입으로 인식을 하지 못했기 때문에 some함수를 찾지 못합니다. 그래서 타입이 User가 되도록 변환을 해줘야 합니다.

  • 명시적 형변환과 타입을 확인으로 자동형변환이 일어나도록 유도하는 예입니다.
class User{
    void some(){
        print("User...some()...");
    }
}

main(List<String> args){
    Object obj = User();

    (obj as User).some();// 명시적 형변환

    if(obj is User){// 아무것도 한것이 없지만 User은 Object에 포함되기 때문에 타입을 확인하는 순간 자동형변환이 일어남
        obj.some();
    }
}

결과)
User...some()...
User...some()...

 

  • 객체생성 후 접근방식
class User{
    String? name;
    int? age;
    void some(){
        print("name: $name, age:$age");
    }
}

main(List<String> args){
    //첫번째 방법
    var user = User();
    user.name = '이제니';
    user.age = 10;
    user.some();

    //두번째 방법
    var user2 = User()..name = '안유진'..age = 30.. some();
}

결과)
name: 이제니, age:10
name: 안유진, age:30

 

7. 실행 흐름의 제어

  • for문의 활용
main(List<String> args){
    var rs = [10, 20, 30];

    print("---------------------");
    for(var i = 0; i < rs.length; i++){
        print(rs[i]);
    }

    print("---------------------");
    for(var x in rs){
        print(x);
    }
}

---------------------
10
20
30
---------------------
10
20
30

 

  • switch~case문
void test(arg){
  switch(arg){
    case 'A':
      print('A');
      break;
    case 'B':
      print('B');
  }
}
main(List<String> args){
  test('A');
  test('B');
}

 

  • 예외 처리 - 에러 던지기
class MyError(){
	String message1(){
    	return "[1234]에러";
    }
    String messageDetail(){
    	return "1234라인에서 에러가 났습니다.";
    }
    throw Exception('MyError - $message1 : $messageDetail');
}

void test(){
  throw '에러 - exception';
}
main(List<String> args){
  test();
}

출력)
Error: 에러 - exception

------------------------------------

void test(){
  throw Exception('전력으로 던지는 exception');
}
main(List<String> args){
  test();
}

출력)
Error: Exception: 전력으로 던지는 exception

------------------------------------

class MyError{
  String message1 = "[1234]에러";
  String messageDetail = "1234라인에서 에러가 났습니다.";
  MyError(String msg){
    throw ('MyError - $message1 : $messageDetail $msg');
  }
}

main(List<String> args){
  throw MyError("에러가 났네");
}

출력)
Error: MyError - [1234]에러 : 1234라인에서 에러가 났습니다. 에러가 났네

-----------------------------------

main(List<String> args){
  try{
    print('stop1...'); //==== 정상실행될때
  }on FormatException{
    print('stop2...');
  }on Exception{
    print('stop3...');
  }finally{
    print('stop4...');//====== 무조건 한번은 실행
  }
  print('stop6...');//모두다 빠져나와서 실행
}

결과)
stop1...
stop4...
stop6...

-----------------------------------

main(List<String> args){
  try{
    print('stop1...');
    throw FormatException('my Exception');
  }on FormatException catch(e){
    print('stop2...$e');
  }on Exception catch(e){
    print('stop3...$e');
  }finally{
    print('stop4...');
  }
  print('stop6...');
}

결과)
stop1...
stop2...FormatException: my Exception
stop4...
stop6...

 

 

By. 유목민 알폰스 - Nomadic Alphonse