KWiOS
KWiOS0101
KWiOS
  • 분류 전체보기 (108)
    • Algorithm (41)
      • 이코테 (14)
      • 이코테 문제풀이 (21)
      • 프로그래머스 (6)
    • CS (1)
      • 모두를 위한 컴퓨터 과학(CS50 2019) (0)
    • iOS (15)
    • Swift (36)
      • Swift문법 (32)
      • 기타 (4)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 6

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
KWiOS

KWiOS0101

Swift/Swift문법

Swift문법 - Functions

2023. 1. 22. 16:15

function

function은 특정 작업을 수행하는 코드 블록으로 자주사용하는 함수를 작성해 놓으면 반복적으로 가져와서 사용할 수 있어 편하며 불필요한 코드의 반복이 줄어든다.

함수 이름은 lowerCamelCase로 지어야 하며 직관적인 이름으로 만드는것이 좋다.

// 함수 작성 기본 문법 
func name(parameters) -> ReturnType { 
	statements
}

// 함수 호출 
name(parameters)

 

함수를 작성하는 방법으로는 아래 예시처럼 작성 가능하다.

1. 반환값이 없는 경우 

func str(name: String) -> Void {
   print(name)
}
str(name: "Swift")

// 반환값이 없는 경우 Void 생략 가능
func str(name: String) {
   print(name)
}
str(name: "Swift")

 

2. 파라미터가 없는 경우 

func maxInt() -> Int {
    return Int.max
}

maxInt() // 9223372036854775807

 

3. 파라미터, 반환값이 없는 경우 

func str() {
	print("hello, Swift")
}    

str() // 함수호출 hello, Swift 출력

// 함수 길이가 짧다면 한줄로 표현 가능
func str() { return print("hello, Swift") }

str()

 

4. 파라미터에 기본값을 미리 지정한 경우 

func str(name: String, age: Int = 28) {
   print("\(name), \(age)")
}

// 함수 호출시 기본값이 지정된 파라미터는 생략 가능
str(name: "Swift") // Swift, 28

str(name: "Swift", age: 30) // Swift, 30

 

5. 아규먼트 레이블을 사용할 경우 

func str(to name: String, from name2: String) {
	
    // 내부에서는 파라미터 이름 사용
    print("\(name), \(name2)") 
}

// 외부에서 호출할 때는 아규먼트 레이블 사용
str(to: "hello", from: "Swift")

 

6. 여러개의 결과 반환하기 

// 하나의 파라미터를 받아 3개의 결과값을 리턴한다.
func sizeConverter(length: Float) -> (yards: Float, centimeters: Float, meters: Float) {
    let yerds = length * 0.0277778
    let cenimeters = length * 2.54
    let meters = length * 0.0254
    return (yerds,cenimeters,meters) // 배열이 아니라 튜플이다.
}

Return Values

리턴 타입이 존재하는 함수로 함수의 반환값이 있음을 의미한다.

// 리턴타입이 있는 함수작성 기본 문법
func name(parameters) -> ReturnType {
    statements
    return expression
}

name(parameters)

 

함수를 작성하는 방법으로는 아래 예시처럼 작성 가능하다.

1. 리턴타입이 Int인 함수 

// 리턴타입 Int
func add() -> Int {
    return 2 * 2
}
add() // 4

 

2. 리턴타입이 String인 함수

// 리턴 타입 String
func strAdd() -> String {
    return "hello" + " Swift"
}
strAdd() // hello Swift 출력

parameters

파라미터는 함수로 전달하는 값을 의미하며 함수 내부에서 사용할 수 있는 임시 상수이다.

// 파라미터가 있는 함수작성 기본 문법
func name(name: Tpye, name: Type) -> ReturnType {
	statements
}

name(paramName: expr, paramName: expr)

 

함수를 작성하는 방법으로는 아래 예시처럼 작성 가능하다.

1. 파라미터 a와 b를 전달받아 a + b의 결과값을 반환

func add(a: Int, b: Int) -> Int {
    return a + b // 9
}
    
add(a: 4, b: 5) // 9

 

2. 파라미터 a와 b를 전달받아 a + b의 결과값을 반환 (b의 기본값 5)

func add(a: Int, b: Int = 5) -> Int {
    return a + b //9
}
    
add(a: 4) //9

 

3. 리턴타입이 없고 파라미터 str을 입력받아 print (str의 기본값 Swift)

func str(str: String = "Swift") {
	print("hello, \(str)")
}

// 새로운 값을 파라미터로 전달할 경우 전달받은 값 사용
str(str: "ki woo") // hello, ki woo

// 아무것도 전달하지 않으면 기본값 사용
str() // hello, Swift

argument Label

파라미터의 가독성을 높이기 위해 사용하며 _ 와일드카드 패턴으로 생략도 가능하다.

함수 호출시에 사용된다. 

 

함수를 작성하는 방법으로는 아래 예시처럼 작성 가능하다.

1. 함수 작성시 아규먼트 레이블을 사용하지 않은 경우 

func str(name: String) {
    print("hello, \(name)")
}

// name은 파라미터이름인 동시에 아규먼트레이블도 된다.
str(name: "Swift")

 

2. 함수 작성시 아규먼트 레이블을 사용한 경우 

func str(to name: String) {
    print("hello, \(name)")
}

// to는 아규먼트 레이블이고 name은 파라미터이름이다.
str(to: "Swift")

 

3. 같은 이름의 함수가 2개일 경우 

func str(name: String) {
    print("hello, \(name)")
}
str(name: "Swift")

func str(to name: String) {
    print("hello, \(name)")
}
str(to: "Swift")
같은 이름의 함수가 2개면 에러가 발생해야 하지만 위 코드는 에러가 발생하지 않는다.
왜냐하면 컴파일러에서
func str(name: String)
func str(to name: String) 
각각 따로 인식하기 때문에 에러가 발생하지 않는다. 
* 같은 이름의 함수가 없으면 아규먼트 레이블을 사용하지 않아도 된다. *

 

4. 아규먼트 레이블을 생략하는 경우 

func str(_ name: String) {
    print("hello, \(name)")
}

// str(to: "Swift") to: 생략 가능하다
str("Swift")

가변 파라미터 

가변 파라미터는 개별 함수마다 하나씩만 사용가능하며 기본값을 가질 수 없다. 

가변 파라미터에 전달되는 값은 배열 형대로 전달된다. 

 

함수를 작성하는 방법으로는 아래 예시처럼 작성 가능하다.

func num(nums: Int...) -> Int {
    var sum = 0
    
    for num in nums {
        sum += num
    }
    
    return sum
}

num(nums: 1,2,3,4,5) // 15
num(nums: 5,6,7) // 18

In-Out Prameters

함수 내부에서 변경된 값은 함수 외부에서 사용할 수 없는데 함수 내부에서 변경된 값이 외부에서도 유지되도록 할때 사용한다.

 

함수를 작성하는 방법으로는 아래 예시처럼 작성 가능하다.

var number = 3
func add(num: inout Int) -> Int{
    num += 1
    return num
}

let x = add(num: &number) // 파라미터로 전달할 변수이름 앞에 &(주소 연산자)를 붙여주어야 한다.
print(x)

 

In-Out 파라미터를 사용하지 않았을 경우 

var number = 3
func add(num:Int) -> Int{
    num += 1 // 함수 내부에서 파라미터는 상수이므로 변경이 불가능하다 (Error!!)
    return num
}

let x = add(num: number)
print(x)

위 코드를 In-Out을 사용하지 않고 In-Out을 사용했을때와 동일하게 동작하도록 하려면 아래와 같이 작성한다. 

var number = 3

func add(num:Int) -> Int{
    
    var result = num // 새로운 변수를 이용해 파라미터로 전달받은 값을 변경
    result += 1 
    return result
}

let x = add(num: number)
print(x)

Function Types

함수 또한 자료형이 존재하며 1급 객체(First Class Citizen)이다.

1급 객체의 특징으로는 

1. 변수나 상수에 대입 가능

2. 파라미터로 전달 가능

3. 함수에서 리턴 가능 

 

위 세가지를 충족하기위해서는 자료형이 필요하다. 

 

함수의 자료형을 표현하는 기본 문법은 아래와 같다.

(Parameter Type) -> Return Type

 

함수를 작성하는 방법으로는 아래 예시처럼 작성 가능하다.

1. 함수의 파라미터와 리턴형이 없는 경우 함수의 자료형

func sayHello() {
    print("Hello, Swift")
}

print(type(of: sayHello())) // ()

 

2. 함수의 파라미터가 있고 리턴형이 없는 경우 함수의 자료형 

func sayHello(name: String) {
    print("Hello", name)
}

print(type(of: sayHello(name:))) // (String) -> ()

 

3. 함수의 파라미터가 없고 리턴형이 있는 경우 함수의 자료형

func sayHello() -> String {
    let resultStr = "Hello"
    return resultStr
}

print(type(of: sayHello())) // String (리턴 타입)

 

4. 함수의 파라미터가 있고 리턴형도 있는 경우 함수의 자료형 

func sayHello(name: String) -> String {
    let resultStr = "Hello" + name
    return resultStr
}

print(type(of: sayHello(name:))) // (String) -> String

 

변수나 상수에 대입

let helloStr = sayHello(name: "Swift")
let helloStr2: (String) -> String = sayHello(name:)

helloStr //"HelloSwift"
helloStr2("Swift") //"HelloSwift"

파라미터로 전달하기 

func add(a: Int, b: Int) -> Int {
    return a + b
}

func calculation(a: Int, b: Int, callBack: (Int,Int) -> Int) -> Int {
   
    let result = callBack(a,b)
    print(result)
    
    return result
}

calculation(a: 10, b: 20, callBack: add(a:b:)) // 파라미터 callBack으로 add함수 전달

함수에서 함수 리턴하기 

func add(a: Int, b: Int) -> Int { return a + b }
func sub(a: Int, b: Int) -> Int { return a - b }
func mul(a: Int, b: Int) -> Int { return a * b }
func div(a: Int, b: Int) -> Int { return a / b }

func selectFunction(from op: String) -> ((Int,Int) -> Int)? {
    switch op {
    case "+":
        return add(a:b:)
    case "-":
        return sub(a:b:)
    case "*":
        return mul(a:b:)
    case "/":
        return div(a:b:)
    default:
        return nil //nil을 리턴받기위해 ((Int,Int) -> Int)? 옵셔널로 해주어야한다.
    }
}

// 상수에 대입해 호출 
let a1 = selectFunction(from: "+")
a1?(1,2)

// 직접 호출 
selectFunction(from: "*")?(2,6)

Nested Function

함수 내부에 함수가 포함되어 있는 함수이다. 

func outer() {
    func inner() {
        print("inner")
    }
    print("outer")
}
outer() 
inner() // 에러 발생

위 코드를 실행해보면 outer 함수는 정상적으로 호출되지만 inner함수는 nested funtion이기 때문에 에러가 발생한다. 

inner함수를 정상적으로 호출되게 하려면 아래 코드와 같이 작성해야 한다. 

func outer() -> () -> () {
    
    func inner() {
        print("inner")
    }
    
    print("outer")
    
    return inner
}

outer()()

먼저 outer 함수를 호출하고 반환된 inner함수를 한번더 호출해줌으로써 outer함수 내부에 있는 Inner함수를 호출할 수 있다.


Implicit Return (암시적 변환)

함수에서 return을 생략할 수 있지만 함수 바디에 2개의 표현식이 있다면 생략할 수 없다.

 

1. 함수 내부에 1개의 표현식만 있을 경우 

func add(a: Int, b: Int) -> Int {
    a + b //return a + b
}

add(a: 1, b: 2)

 

2. 함수 내부에 2개의 표현식이 있을 경우 

func add(a: Int, b: Int) -> Int {
    let result = a + b
    return result // return을 생략하고 result만 작성시 Error!!
}

add(a: 1, b: 2)

'Swift > Swift문법' 카테고리의 다른 글

Swift문법 - Tuples  (0) 2023.02.05
Swift문법 - Closure  (0) 2023.01.28
Swift문법 - Optional  (1) 2023.01.15
Swift문법 - Control Transfer Statements, Labeled Statements  (0) 2023.01.08
Swift문법 - Loop Statements  (0) 2022.12.23
    'Swift/Swift문법' 카테고리의 다른 글
    • Swift문법 - Tuples
    • Swift문법 - Closure
    • Swift문법 - Optional
    • Swift문법 - Control Transfer Statements, Labeled Statements
    KWiOS
    KWiOS

    티스토리툴바