[Swift] 함수 정의 방법

승민·2024년 10월 5일
0

iOS

목록 보기
4/12
post-thumbnail

출처 : Smile Han - iOS 프로그래밍 기초

Swift의 기초 문법을 활용하여 함수를 정의해볼 거에요.
함수는 반복되는 부분을 최소화시켜주는 아주 고마운 기능이에요.
함수를 만들고 수정하는 방법을 학습하며 원하는 구현해볼 수 있어요!

기초 문법

함수를 정의하기 위해서는 그 내용에 어떤 문법이 들어가야 하는지 알아야겠죠?
본격적인 내용을 다루기에 앞서 간단하게 Swift의 기초 문법을 짚고 넘어가 볼게요.

선언과 출력

Swift에서 변수를 선언하는 방법과 해당 변수의 자료형을 확인하는 방법 및 print함수를 통해 변수 값을 출력하는 방법이에요.

var x = 10
print(type(of:x))
// Int
print("변수 x의 값은 \(x)");
// 변수 x의 값은 10


타입 어노테이션과 타입 추론

Swift에서 상수와 변수의 타입을 식별하는 방법은 두 가지에요.

첫 번째는 변수 또는 상수가 코드 내에서 선언되는 시점에 타입 어노테이션(type annotation)을 사용하는 거에요.

var userCount : Int = 10 // : Int가 type annotation

두 번째는 선언부에 타입 어노테이션이 없는 경우 스위프트 컴파일러가 상수 또는 변수의 타입을 식별하기 위해 타입 추론(type inference)를 사용해요.

var x = 2.231 // var x : Double = 2.231

이 경우 해당 상수 또는 변수에 값이 할당되는 시점에서 그 값의 타입을 확인하고 같은 타입처럼 사용해요.

변수와 상수

변수는 선언한 이후에도 값 변경이 가능해요.

var x = 10
print(x) // 10
x = 20
print(x) // 20 , 문제 없음


하지만 상수는 선언하면 변경이 불가능해요.

let x = 10
print(x) // 10
x = 20 // 에러 발생
print(x)


튜플

튜플은 여러 값을 하나의 개체에 일시적으로 묶는 방법이에요.
괄호 안에 콤마로 구분되어 있어요.

특정 튜플 값은 인덱스 위치를 참조하여 간단하게 접근할 수 있어요.(첫 번째 값의 인덱스는 0이에요.)

let myTuple = (10, 12.1, "Hi")
var myString = myTuple.2
print(myString) // Hi


튜플의 값은 선택적으로 추출할 수 있어요. 특정 값의 위치에 밑줄을 사용하여 무시할 수 있고, 각 값의 이름을 할당할 수도 있어요.

let myTuple = (count: 10, length: 12.1, message: "Hi")
var (myInt, _, myString) = myTuple // 12.1 값 무시
print(myTuple.message, myTuple.2)


그 외 다른 문법

연산자, 반복문, 제어문, 옵셔널에 관한 내용은 이전 포스트에서 다루었기 때문이 이전 포스트를 확인해주세요!

#3 [iOS] Swift의 자세한 기초 문법

함수

함수는 특정 작업을 수행하는 코드 블록으로 정의할 수 있어요!
데이터를 전달하거나 호출한 곳에서 작업 결과를 전달받을 수 있어요.
그러나 이를 지칭하는 매개변수와 인수는 차이점이 존재해요!


매개변수(parameter)와 인수(argument)라는 용어는 다양한 프로그래밍 언어에서 서로 다른 의미를 가질 수 있습니다. 때로는 이 두 용어가 서로 바꿔 쓰이기도 하며, 문맥에 따라 의미가 구분됩니다. 매개변수(때때로 형식 매개변수(formal parameter)라고도 함)는 함수 정의에서 발견되는 변수를 지칭하는 데 자주 사용되는 반면, 인수(때때로 실제 매개변수(actual parameter)라고도 함)는 함수 호출 시 제공되는 실제 입력을 가리킵니다.

The terms parameter and argument may have different meanings in different programming languages. Sometimes they are used interchangeably, and the context is used to distinguish the meaning. The term parameter (sometimes called formal parameter) is often used to refer to the variable as found in the function definition, while argument (sometimes called actual parameter) refers to the actual input supplied at function call.

원문 출처 : en.wikipedia.org


함수에서 정의부 값은 매개변수, 호출시 값은 아규먼트라고 불러요!

#include <stdio.h>

void Fun(int Param) { // // parameter(매개변수, 인자), 형식 매개변수(formal parameter)
	printf("%d", Param);
}

int main() {
	Fun(10); // 10은 argument(인수), 실 매개변수(actual parameter)
    return 0;
}

메서드

메서드는 특정 클래스, 구조체, 열거형 내의 함수를 뜻해요.
함수를 클래스 내에 선언하면 메서드라고 부르죠!

함수와 메서드가 헷갈리는 경우를 위해 다음과 같이 구분할 수 있어요!


함수가 단독적으로 존재하는 경우 : 함수(Function)
함수가 클래스, 구조체 등 안에 존재하는 경우 : 메서드(method)


그렇기 때문에 자바항상 클래스 안에 함수가 존재하기 때문에 자바에서는 함수라고 하지 않고 메서드라고 해요!

함수를 선언하는 방법

이제 Swift에서 함수를 선언하는 방법에 대해서 알아볼게요!
먼저 어떤 형식을 통해 선언해야 하는지 확인해볼게요.

각 내용에 대해 자세한 설명이 있지만, 조금 더 빠른 이해를 위해 실제 예제를 통해 알아볼게요!

func sayHello() {
    print("Hello")
}
sayHello() // 호출, Hello


이렇게 함수를 선언하고 호출을 해줌으로써 코드의 중복되는 부분을 줄여줄 수 있어요!
다양한 시각으로 접근하는 것이 이해에 도움이 되기 때문에 C언어에서 함수를 선언하는 방법과 비교해볼게요!


int add(int x, int y) {
	return(x+y);
}
add(10, 20);


func add(x: Int, y: Int) -> Int {
	return(x+y);
}
add(x:10, y:20)


함수 만드는 내용에 대해 차이점을 확인해보면 ->를 통해 리턴형을 지정하고 있고, 인자값에 대해서 :을 통해 자료형을 지정하고 있다는 것을 알 수 있어요.
이 부분 이외에는 크게 다르진 않네요!
또한 Swift의 type함수를 이용하면 함수의 리턴형을 확인할 수 있어요.

func add(x: Int, y: Int) -> Int {
    return(x+y);
}
print(type(of: add))


함수 매개변수 이름

Swift에서는 함수의 내부 매개변수(parameter name) 이름과 외부 매개변수(argument label) 이름을 지정할 수 있어요.
함수를 정의할 때, 불러지는 이름을 지정하면 함수를 호출할 때 지정한 이름으로만 호출할 수 있어요!

더 정확한 이해를 위해 코드로 확인해볼게요!

func add(first x: Int, second y: Int) -> Int {
    return(x+y)
}
var num = add(first:10, second:20)
print(num)


기존과 비슷한 형식이지만 변수 이름 앞에 또 다른 이름을 적어줌으로써 이름을 지정할 수 있어요!

이 코드에서 add 함수 안에 있는 first외부 매개변수명(argument label)이라 하고, x내부 매개변수명(parameter name)이라고 해요!

그리고 호출할 때는 외부 매개변수명을 사용해야 하죠.

잘못된 사용을 방지하기 위해 Swift에서는 다음과 같은 경우에 에러를 표시해요!

  • 외부 매개변수명을 함수 안에서 사용하는 경우


  • 내부 매개변수명으로 함수를 호출한 경우


각각 지정해준 이름을 사용해야 하기 때문에 외부 매개변수명내부 매개변수명을 잘 구분해줄 필요가 있어요!

함수의 Type

위 내용처럼 Swift에서는 함수의 외부, 내부 매개변수 명을 지정하거나 생략( _ )할 수 있기 때문에 같은 이름의 함수라도 호출하는 방식에 따라서 다른 내용을 가질 수 있어요!

각각 어떤 부분이 다른지 코드를 통해서 확인해볼게요!

func add(x: Int, y: Int) -> Int {
    return (x+y)
}
print(add(x: 10, y: 20))

func add(first x: Int, second y: Int) -> Int {
    return (x+y)
}
print(add(first: 10, second: 20))

func add(_ x: Int, _ y: Int) -> Int {
    return (x+y)
}
print(add(10, 20))

func add(_ x: Int, with y: Int) -> Int {
    return (x+y)
}
print(add(10, with:20))


위 4가지 함수는 모두 달라요!
각각 선언되는 방식이 다르기 때문이에요.

이런 경우에 함수 안에 print(#function)을 통해서 각 이름을 확인해볼 수 있어요!

코드로 확인해볼게요.

func add(x: Int, y: Int) -> Int {
    print(#function)
    return (x+y)
}
print(add(x: 10, y: 20))

func add(first x: Int, second y: Int) -> Int {
    print(#function)
    return (x+y)
}
print(add(first: 10, second: 20))

func add(_ x: Int, _ y: Int) -> Int {
    print(#function)
    return (x+y)
}
print(add(10, 20))

func add(_ x: Int, with y: Int) -> Int {
    print(#function)
    return (x+y)
}
print(add(10, with:20))


이렇게 하면 함수를 호출했을 때, 어떤 함수를 호출했는 지 이름을 확인할 수 있어요!

출력된 내용을 보면 각각 add(x:y:), add(first:second:), add(_:_:), add(_:with:) 이렇게 출력된 것을 확인할 수 있어요.

여기서 중요한 점! 이 함수의 이름은 add가 아니라 add(x:y:)까지가 이름이에요! 그러니 각각의 함수가 다 다른 이름인거죠!

이전까지는 하나의 함수 이름이라고 했지만, 이제부터는 함수 이름은 괄호 부분까지 포함해요!

이를 #function 리터럴(literal)이라고 해요!

관련 공식문서 : docs.swift.org


내용을 보면 한 가지 특이한 방식이 있어요. 바로 add(_:with:)로 작성된 내용이에요. 이는 Swift 이전의 Objective-C 언어의 호출 방식이 이렇기 때문이에요. 두 번째 매개변수부터 외부 매개변수를 사용하는 것이지요.


이렇게 Swift의 함수에 대해 알아봤으니 다른 언어의 함수를 변환할 줄 알아야 겠죠? C/C++ 함수를 Swift 함수로 변환해볼게요.

int ddd(int x) {
    return (x * 2);
}

void setX(int x) {
    xx = x;
}

int getX() {
    return xx;
}

int add(int x, int y) {
    return (x + y);
}

void setXY(int x, int y) {
    xx = x;
    yy = y;
}

이 내용을 Swift 언어로 변환해볼게요.

func ddd(_ x: Int) -> Int {
    return x * 2
}

func setX(_ x: Int) {
    xx = x
}

func getX() -> Int {
    return xx
}

func add(_ x: Int, with y: Int) -> Int {
    return x + y
}

func setXY(_ x: Int, second y: Int) {
    xx = x
    yy = y
}

함수명과 함수 자료형(type)

어떤 함수를 공부한다고 하면 함수를 찾아볼 때, 보통 함수 이름은 같고 두 번째 인자의 이름이 다른 것을 알 수 있어요.

이런 경우 두 번째 인자 이름을 검색해서 어떤 내용으로 이루어져있는지 확인할 수 있어요!

이렇게 이름이 복잡하고 길게 작성된 이유는 영어권에서 이 내용을 쭉 나열하면 하나의 문장처럼 보이기 때문에 이렇게 작성되었다고 하네요.

공식 문서 : 테이블 뷰 전체 내용

공식 문서 : 함수 tableView(_:numberOfRowsInSection:)


실전에서는 이런 공식문서를 잘 찾아봐야겠죠?
그러나 보통 자주 사용하는 함수는 기억하는 것이 좋아요. 자주 사용하니까요!

iOS 테이블뷰에서 많이 사용하는 메서드

그렇기 때문에 어떤 내용들이 자주 사용되는지 확인해볼게요.
아래 내용은 ChatGPT가 답변한 내용이에요!


iOS에서 UITableView는 목록 기반의 데이터를 화면에 보여줄 때 매우 자주 사용됩니다. UITableView를 사용할 때 필수적인 메서드와 많이 사용하는 메서드들이 몇 가지 있으며, 일반적으로 사용 빈도 순으로 나열하고 설명을 드리겠습니다.

1. numberOfRowsInSection

  • 메서드 서명: func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
  • 기능: 해당 섹션(section)에 몇 개의 행(row)이 있는지 반환합니다. 테이블 뷰의 데이터 원본에서 각 섹션에 몇 개의 행을 표시할지 정의합니다.
  • 예시:
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataArray.count
    }
  • 설명: dataArray라는 배열에 있는 항목의 개수만큼 행을 표시합니다.

2. cellForRowAt

  • 메서드 서명: func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
  • 기능: 특정 인덱스 경로에 있는 셀을 생성하고 반환합니다. 이 메서드는 각각의 행에 대해 테이블 뷰 셀을 구성합니다.
  • 예시:
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)
        cell.textLabel?.text = dataArray[indexPath.row]
        return cell
    }
  • 설명: 재사용 가능한 셀을 가져와서 dataArray 배열에서 데이터 값을 설정한 후 반환합니다.

3. numberOfSections

  • 메서드 서명: func numberOfSections(in tableView: UITableView) -> Int
  • 기능: 테이블 뷰에서 섹션의 개수를 반환합니다. 테이블 뷰가 섹션이 여러 개인 경우에 사용됩니다.
  • 예시:
    func numberOfSections(in tableView: UITableView) -> Int {
        return sectionArray.count
    }
  • 설명: sectionArray 배열의 길이에 맞춰 섹션의 개수를 반환합니다.

4. didSelectRowAt

  • 메서드 서명: func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
  • 기능: 특정 행이 선택되었을 때 호출됩니다. 사용자가 테이블 뷰의 특정 행을 선택했을 때의 행동을 정의할 수 있습니다.
  • 예시:
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("Selected row: \(indexPath.row)")
    }
  • 설명: 선택한 행의 번호를 콘솔에 출력합니다.

5. heightForRowAt

  • 메서드 서명: func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
  • 기능: 특정 인덱스 경로에 있는 행의 높이를 반환합니다. 이 메서드를 사용하여 각 셀의 높이를 다르게 설정할 수 있습니다.
  • 예시:
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 60.0
    }
  • 설명: 모든 행의 높이를 60 포인트로 설정합니다.

6. viewForHeaderInSection

  • 메서드 서명: func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
  • 기능: 각 섹션의 헤더에 커스텀 뷰를 제공합니다. 이 메서드를 사용하여 섹션 헤더를 커스터마이징할 수 있습니다.
  • 예시:
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerView = UIView()
        headerView.backgroundColor = .lightGray
        return headerView
    }
  • 설명: 회색 배경을 가진 커스텀 섹션 헤더 뷰를 반환합니다.

7. titleForHeaderInSection

  • 메서드 서명: func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
  • 기능: 각 섹션에 표시할 텍스트 헤더를 반환합니다.
  • 예시:
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "Section \(section)"
    }
  • 설명: 각 섹션 번호에 맞는 문자열을 반환하여 해당 섹션의 제목으로 사용합니다.

정리:

위에서 언급한 메서드는 UITableView에서 자주 사용되는 메서드들입니다. 기본적으로 테이블 뷰의 데이터를 표시하고 셀을 관리하는 데 사용되는 메서드로, 이외에도 다양한 델리게이트 메서드를 추가하여 세부 동작을 정의할 수 있습니다.

  1. numberOfRowsInSection - 행 개수 설정
  2. cellForRowAt - 셀 구성
  3. numberOfSections - 섹션 개수 설정
  4. didSelectRowAt - 선택된 셀에 대한 처리
  5. heightForRowAt - 셀 높이 설정
  6. viewForHeaderInSection - 커스텀 섹션 헤더 뷰
  7. titleForHeaderInSection - 섹션 헤더 타이틀

이 외에도 UITableView에는 다양한 메서드들이 있으며, 필요에 맞춰 델리게이트 및 데이터 소스 메서드를 구현하여 사용할 수 있습니다.

답변 출처 : ChatGPT


이렇게 Swift의 간단한 기초 문법을 다시 알아보았고, 함수가 어떻게 구성되었고 어떤 부분이 다른지 확인할 수 있었어요!

0개의 댓글