iOS 스터디용으로 만든 강의 자료
변수(variable): 값을 수정할수 있음
상수(constant): 값을 수정할수 없음
var 키워드를 이용해서 변수 선언
var num = 5
num = 1 // 값 수정 가능
let 키워드를 이용해서 상수 선언
let name = "Jason"
name = "Jay" // 값 수정 불가능
// 장점: 코드가 안전해짐, 컴파일러가 최적화를해서 실행속도가 빨라짐
| var a: String | 타입 명시 (Explicit)→ 변수 a는 반드시 String 타입이어야 함 |
|---|---|
| var a = "aaa" | 타입 추론 (Type Inference)→ Swift가 "aaa"를 보고 자동으로 a가 String이라고 판단 |
Swift는 타입 추론이 강력한 언어
하지만 복잡한 상황에서는 타입을 명시해주면 가독성도 좋고, 실수도 줄어듦
공식 문서나 현업 코드에서도 둘 다 쓰이는데, 상황에 따라 선택하는 게 중요
import Foundation
let str = "1" // 이것도 문자열
type(of: str)
let ch: Character = "1" // 한개의 문자를 저장하는 타입을 지정하고 싶으면 Character 타입 명시
type(of: ch)
let doublech: Character = "AA" // 오류. 한개의 문자만 저장가능
let emptyCh: Character = " "// 오류. 두개이상 공백 저장불가능. 한개의 공백만 저장 할 수 있음
import Foundation
let s = "Hello world"
let lorenIPut = "elwdjwelkdwe lknwekjdnekwdnkwedjnewkjndekwj ndkewjnkejwnckdjsnckjdsncksndknkfnwekfj nwekjnfewnfkjenfkjewnfkjnfnefkewjfnwkefnkjwef nkjnfkj enfkjwenfkjnfjkewn fkjewnfkjw nfkwnfkfnkjnew"
print(lorenIPut)
// 큰따옴표 3개는 multiline literal 이라서 줄 바꿈을 해줄수 있음
let multiline =
"""
dwdwdkjdnkjdlkwdlkdjl,
wlndnwkjndkwnjdknwdkw,
wendjkwendkjewndkjwend,
dnkwjndkwjdnekwjndwekjndjkwdn
""" // 닫는 따옴표가 문자열의 문장보다 앞이나 동일선상에 있어야함
print(multiline)
var nsstr: NSString = "str" //Objective-C 스타일 문자열(클래스)
let swiftStr: String = nsstr as String //nsstring을 string에 저장하려면 표현해줘야함
var str = "Hello" // 연결하려면 let말고 var을 사용해야함
str.append("Swift") // str에 문장추가함수
let c: Character = " " // 빈 character type을 선언하려면 공백을 추가해줘야함
import Foundation
var str = "Hello, Swift String"
var emptyStr = "" // 빈문자열 선언
emptyStr = String()
let a = String(true) // 다른 타입을 문자열로만들기
let b = String(12)
let c = String(12.34)
let d = String(str)
let hex = String(123, radix: 16) // 123을 16진수로 바꾸는 코드. radix를 8로 하면 8진수, 2로 하면 2진수
let repeatStr = String(repeating: "Hi", count: 5) // 문자를 반복하는 코드
print(repeatStr)
let clap="\u{1f44f}" // 유니코드. 박수모양
print(clap)
// String 연결
let e = "\(a)\(b)" // 이렇게해서 연결 가능
let f = a + b // + 연산자를 이용해서 연결 가능
str += "!!" // 이렇게 바로뒤에 붙이는거도 가능
//String 내장 함수
str.count // 문자열의 글자수
str.count == 0 // 문자열이 비어있는지
str.isEmpty // 문자열이 비어있는지
str.uppercased() // 문자열을 모두 대문자로 바꾸는 함수
str.lowercased() // 문자열을 모두 소문자로 바꾸는 함수
str.capitalized // 문자열의 속한 어절의 첫번째 문자를 대문자로, 나머지는 모두 소문자로
let num = "1234567890"
num.randomElement() // 랜덤한 문자값 1개 추출
String(num.shuffled()) // 문자열의 문자순서를 랜덤으로
str == "Apple"
"apple" != "Apple" // 아스키 코드로 비교(대소문자 구분)
"apple" < "Apple"
for char in "Hello"{ // 문자열에 있는 문자를 순서대로 출력. 배열처럼 이용가능
print(char) // playground 환경에서 제대로 출력되지 않음
}
import Foundation
var str = "Hello"
str.append(", ") // str뒤에 새로운 문자열 추가
str // str 값이 변함
let s = str.appending("Swift") // 새로운 문자열에 str뒤에 새로운 문자열 추가
str // str 값이 변하지 않음
s
"File size: ".appendingFormat("%.1f", 12.345) // 원본을 바꾸지 않고 새로운 문자열을 리턴
str.insert(",", at: str.index(str.startIndex, offsetBy: 5)) // 문자열 중간에 문자를 추가
if let sIndex = str.firstIndex(of: "H"){ // str의 첫번째 문자가 H인지 검사, sIndex에 첫번째라는 값을 넣음
str.insert(contentsOf: "Awesome", at: sIndex) // H위치(첫번째)에 문자열 추가
} // 검사할때는 새로운 상수를 만들어서 검사해야함
import Foundation
var str = "Hello, Objective-C"
if let range = str.range(of: "Objective-C") { // Objective-C 부분을 탐색
str.replaceSubrange(range, with: "Swift") // 탐색한부분을 Swift로 변경
}
str
if let range = str.range(of: "Hello") { // str은 바뀌지 않음
let s = str.replacingCharacters(in: range, with: "Hi")
s
str
}
var s = str.replacingOccurrences(of: "Swift", with: "Awesome Swift") // Swift부분을 변경. str의 값은 바뀌지 않음.
s
s = str.replacingOccurrences(of: "swift", with: "Awesome Swift") // 대소문자를 구분함
s
s = str.replacingOccurrences(of: "swift", with: "Awesome Swift", options: [.caseInsensitive])
// 대소문자를 무시하고 문자열을 비교하는 옵션을 추가해야함
s
str = "Hello, Awesome Swift!!!"
let lastCharIndex = str.index(before: str.endIndex) // 마지막 인덱스를추출
var removed = str.remove(at: lastCharIndex) // 추출한 인덱스를 삭제
removed
str
removed = str.removeFirst() // 첫번째 문자를 삭제하고 삭제한 문자를 리턴. str의 첫번째 삭제, removed = 삭제된문자
str.remove(at: str.startIndex)
str.removeFirst(2) // 앞에서 두번째까지 삭제
str
str.removeLast(2) // 뒤에서 두번째까지 삭제
if let range = str.range(of: "Awesome"){ // "Awesome 부분을 삭제
str.removeSubrange(range)
str
}
str.removeAll() // 문자 모두 삭제
str.removeAll(keepingCapacity: true) // 메모리 공간은 삭제하지 않음. 불필요한 메모리공간 오버헤드 방지
str = "Hello, Awesome Swift!!!"
var substr = str.dropLast() // 원본 문자열에서 마지막 문자하나를 뺀 문자열을 리턴
substr = str.dropLast(3) // 마지막에서 3번째까지 뺀 문자열을 리턴
substr = str.dropFirst()
substr = str.dropFirst(7) // 첫번째에서 7번째까지 뺀 문자열을 리턴
import Foundation
let str = "Swift"
str.startIndex // 첫번째 인덱스
let firstCh = str[str.startIndex]
print(firstCh)
let lastCharinDex = str.index(before: str.endIndex) // 문자열의 마지막은 nil이므로 마지막의 이전값을 추출
let lastch = str[lastCharinDex]
print(lastch)
let seconcharIndex = str.index(after: str.startIndex)
let secondCh = str[seconcharIndex]
print(secondCh)
var thirdCharIndex = str.index(str.startIndex, offsetBy: 2) // 문자열의 3번째 인덱스 추출. 첫번째인덱스에서 두번째. (1+2)번째
var thirdCh = str[thirdCharIndex] // index함수를 이용해서 문자열의 인덱스를 자유롭게 추출가능.
print(thirdCh)
thirdCharIndex = str.index(str.endIndex, offsetBy: -3) // 문자열의 3번째 인덱스 추출. 마지막 인덱스에서 3번째 이전. (6-3)번째
thirdCh = str[thirdCharIndex]
print(thirdCh)
if thirdCharIndex < str.endIndex && thirdCharIndex >= str.startIndex{
} // swift는 유니코드 문자를 처리할때 내부 할당값이 아니라 사람이 인식하는 문자로 처리해서 StringIndex 사용
import Foundation
let nums = [1, 2, 3]
let multi = [[1, 2, 3],[4, 5, 6]]
let strArray: Array<String>
let strArray2: [String]
// 비어있는 배열 선언
let emptyArray: [Int] = []
let emptyArray2 = Array<Int>()
let emptyArray3 = [Int]()
let zeroArray = [Int](repeating: 0, count: 10) // 같은 값을 배열에 넣을때 사용
nums.count // 배열의 인덱스 수
nums.count == 0 // 배열이 비어있는지 비교
nums.isEmpty // 배열이 비어있는지 검사하는 함수
let fruits = ["Apple", "Banana", "Melon"]
fruits[0] // 첫번째 요소의 문자열을 가져옴
fruits[fruits.startIndex] // 첫번째
fruits[fruits.index(before: fruits.endIndex)] // 마지막
fruits.first // 첫번째. 안전하게 접근 가능함
fruits.last // 마지막. 안전하게 접근 가능함
let list = ["A", "B", "C", "D", "E"]
list[0...2] // 첫번째부터 3번째까지
list[2...] // 3번째부터 마지막까지
list.prefix(3) //3번째까지 리턴
list.prefix(upTo: 3) // 3번째까지
list.prefix(through: 3) // array[3] 까지
let r = list.prefix {$0 != "C"} // 앞에서부터 C가 나올때까지 리턴
list.suffix(3) // 뒤에서 3개까지 리턴
list.suffix(from: 3) // 뒤에서 array[3] 까지 리턴
var alphabet = ["A", "B", "C"]
alphabet.append("E") // 배열 뒤에 새로운 원소추가
alphabet.append(contentsOf: ["F","G"]) // 여러개를 동시에 추가
alphabet.insert("D", at: 3) // alphabet[3] 위치에 D 추가
alphabet.insert(contentsOf: ["a", "b", "c"], at: 0) // alphabet[0]에 원소 여러개 동시추가
alphabet.remove(at: 0) // 0번째 삭제
alphabet.removeLast() // 마지막 삭제
alphabet.removeFirst() // 첫번째 삭제
alphabet
let l = alphabet.popLast() // 마지막 삭제 후 삭제한 값 리턴
print(l!) // 옵셔널로 되어있어서 언래핑 해줌
let f = alphabet.dropFirst() // 첫번째 삭제 후 삭제된 배열 리턴
print(f)
let ld = alphabet.dropLast()
let dropw = alphabet.drop(while: { $0 != "C" })
// 배열을 탐색하면서 C가 나올때까지 탐색하면서 C가 아닐때는 드랍하고 C가 나오면 남은 배열 리턴
alphabet.removeSubrange(0...2) // 범위 삭제(출력값은 삭제 된 후 배열)
print(alphabet) // 출력방식
print(Array(alphabet)) // 타입을 명시한 출력방식
alphabet.removeAll() // 모두 삭제
let a = ["A", "B", "C"]
let b = ["a", "b", "c"]
// 배열의 비교
a == b // 대소문자를 구분함(false)
a != b // (true)
a.elementsEqual(b) // 배열이 같은지 비교하는 메소드
//대소문자를 무시하고 같은지 비교
a.elementsEqual(b, by: {(lhs, rhs) -> Bool in return lhs.caseInsensitiveCompare(rhs) == .orderedSame})
// 원소 검색
let randomNumber = [1, 2, 3, 1, 4, 5, 2, 6, 7, 5, 0]
randomNumber.min() // 가장 작은 수를 찾는 메소드
a.min() // 아스키 코드가 가장 작은 원소를 찾음
randomNumber.max() // 가장 큰 수를 찾는 메소드
randomNumber.contains(1) // 해당값이 존재하는지 확인하는 메소드
let r3 = randomNumber.contains {$0.isMultiple(of: 2)} // 짝수가 포함되어있는지 확인
randomNumber.first // 첫번째 탐색
randomNumber.first {$0.isMultiple(of: 2)} // 가장먼저 탐색된 짝수
randomNumber.firstIndex { $0.isMultiple(of: 2)} // 가장 먼저 탐색된 짝수의 인덱스가 몇번째인지 탐색
randomNumber.firstIndex(of: 5) // 첫번째로 검색된 5의 인덱스가 몇번째인지 탐색
randomNumber.lastIndex(of: 5) // 뒤에서부터 검색했을때 첫번째로 검색된 5의 인덱스가 몇번째인지 탐색
//배열의 정렬
randomNumber.sorted() // 오름차순으로 정렬. 하지만 원본은 바뀌지 않음
let sortedNum = randomNumber.sorted() // 뒤에 ed가 붙어서 원본이 바뀌지 않음.
let sorted = randomNumber.sorted { $0 > $1 } // 내림차순으로 정렬
[Int](randomNumber.sorted().reversed()) // 내림차순으로 정렬. 생성자로 전달함.
var mutableNums = randomNumber // 원본을 바꾸는 정렬은 let으로 못하므로 var로 선언된 배열을 사용해야함
mutableNums.sort() // 원본을 정렬하는 메소드
mutableNums.reverse() // 원본을 뒤집는 메소드
mutableNums.swapAt(0, 1) // 0번 인덱스와 1번 인덱스의 자리를 바꿔주는 메소드
mutableNums.shuffle() // 원본 배열의 순서를 셔플해주는 메소드
randomNumber.shuffled() // 원본 배열의 변화없이 순서를 셔플해주는 메소드
import Foundation
var dict = ["A": "Apple", "B": "Banana"]
dict = [:] // 딕셔너리가 공백 상태
let dict1: Dictionary<String,Int> // 정식문법
let dict2: [String: Int] // 단축문법
//빈 딕셔너리
dict = [:]
dict = [String: String]() // 문자열 타입의 딕셔너리
dict = Dictionary<String, String>() // 문자열 타입의 딕셔너리. 위 코드와 같은 의미
let words = ["A": "Apple", "B": "Banana", "C": "City"]
words.count // 딕셔너리 원소의 수
words.isEmpty
words["A"] // 키를 부르면 값을 리턴함(순서가 없음)
words["Apple"] // Apple 라는 키가 없어서 nil을 리턴함.
let a = words["E"] // E라는 키가 없어서 nil을 리턴
let b = words["E",default: "Empty"] // E라는 키가 없으면 기본값을 리턴
for k in words.keys { // 딕셔너리는 정렬되어있지 않음
print(k) // 매번 다른값이 출력됨
}
for v in words.values { // 값도 정렬되어있지 않음
print(v)
}
for k in words.keys.sorted(){ // 정렬하려면 sorted 함수를 사용해야함
print(k)
}
let keys = Array(words.keys) // 키 값을 배열로 저장
let values = Array(words.values) // 밸류값을 배열로 저장
var mutableDict = [String: String] ()
mutableDict["A"] = "Apple" // 키가 없으면 새로운 요소로 저장
mutableDict["B"] = "Banana"
mutableDict.count
mutableDict
mutableDict["B"] = "Ball" // 키가 있으면 그 키에 새로운 값을 저장
mutableDict
mutableDict.updateValue("City", forKey: "C") // C라는 키와 같이 추가
mutableDict.updateValue("Circle", forKey: "C")
mutableDict
mutableDict["B"] = nil // B라는 키와 그 값을 삭제
mutableDict
mutableDict["Z"] = nil // 키가 없으면 동작 되지 않음
mutableDict.removeValue(forKey: "A") // A키를 삭제
mutableDict.removeValue(forKey: "A") // 키가 없으면 동작 되지 않음
mutableDict.removeAll() // 모두 삭제
let first = ["A": "Apple", "B"/*"b"*/: "Banana", "C": "City"] // 출력의 순서는 랜덤
let second = ["A": "Apple", "C": "City", "B": "Banana"]
first == second // false. 키의 대소문자를 구분하므로 false. 딕셔너리의 순서는 상관없음.
first != second // ture
let find: ((key: String, value: String)) -> Bool = { // 딕셔너리가 존재하는지 확인
$0.key == "B" || $0.value.contains("i")
}
first.contains(where: find)
first.first(where: find) // 가장 처음 찾은 딕셔너리를 찾음. 순서가 따로없기 때문에 순서가 매번 달라질 수 있음
first.filter(find) // 검색된 모든 메소드를 새로운 딕셔너리로 리턴. 항상 같은 요소가 포함되어 있음.
• iOS 앱 데이터는 거의 배열/딕셔너리 형태로 다룬다 (예: JSON 파싱, 리스트, 필터링 등)
• 배열/딕셔너리에 익숙하지 않으면 TableView, CollectionView 활용도 어려움
import Foundation
enum Alignment { // 열거형의 이름이 정해졌으므로 케이스 이름은 간단하게
case left // case는 값이 바뀌지 않음
case center
case right
}
var textAlignment = Alignment.center
textAlignment = .left // 무슨 열거형인지 알고 있으므로 열거형의 이름을 생략하고 .만 입력해도 됨.
if textAlignment == .center {
}
switch textAlignment { // 열거형은 스위치문을 사용하는것이 간편함
case .left:
print("left")
case .center:
print("center")
case .right:
print("right")
}
"A".caseInsensitiveCompare("a") == .orderedSame // 대소문자를 구분하지 않음.
import Foundation
enum Alignment: Int {
case left
case right = 100
case center
}
Alignment.left.rawValue
Alignment.right.rawValue
Alignment.center.rawValue // 원시값을 자동으로 저장하지 않으면 기준값(이전의 값) 보다 +1
Alignment(rawValue: 0) // 0번째 열거형
Alignment(rawValue: 200) // 해당하는 값이 없으므로 nil
enum Weekday: String {
case sunday
case monday = "Mon"
case tuesday
case thursday
case friday
case saturday
}
Weekday.sunday.rawValue // 원시값이 없으면 케이스 이름과 똑같은 값이 원시값으로 저장됨
Weekday.monday.rawValue // 직접 저장한 원시값을 가져옴
enum ControlChar: Character {
case tap = "\t" // Character 타입이라 하나의 값을 저장해야함
case newLine = "\n"
}
import Foundation
enum DataParsingError: Error {
case invalidType
case invalidField
case missingRequiredField(String)
}
func parsing(data: [String: Any]) throws {
guard let _ = data["name"] else {
throw DataParsingError.missingRequiredField("name")
}
guard let _ = data["age"] as? Int else {
throw DataParsingError.invalidType
}
//Parsing
}
//try parsing(data: [:]) // 에러를 전달하는 코드를 사용할때 try를 사용. 글로벌 스코프에서는 거의 사용하지 않음.
func test() { //함수내에서 try를 사용하려면, do-catch를 필수적으로 사용해야함
do {
try parsing(data: ["name": ""])
} catch DataParsingError.invalidType, DataParsingError.invalidField {
// catch블록에 순서를 바꿔도 오류는 안남. 하지만 두번째 블록은 실행되지 않음.
print("handle invalidType error")
} catch { // 패턴을 생략한 catch블록은 마지막에 작성해야함.
print("handle error")
if let error = error as? DataParsingError { // 패턴이 없는 에러 처리하는 방법
switch error {
case .invalidType:
print("invalidType")
default:
print("handle error")
}
}
}
}
test()
import Foundation
enum DataParsingError: Error { // Error 프로토콜을 채용하면 Error 타입이됨.
case invalidType
case invalidField
case missingRequiredField
}
// 에러를 던지고(throw) 전달받은 에러처리 코드에서 발생한 에러를 확인하고, 원하는 방식으로 처리
func parsing(data: [String: Any]) throws {
guard let _ = data["name"] else {
throw DataParsingError.missingRequiredField // throw문이 호출되면, 이 함수에서 나머지 코드는 호출하지 않음.
}
guard let _ = data["age"] as? Int else {
throw DataParsingError.invalidType
}
//Parsing
}
try? parsing(data: [:])
import Foundation
let id = "root"
let password = "1234qwer"
if id == "root"{
print("valid id")
}
if password == "1234qwer"{
print("valid password")
}
if id == "root" && password == "1234qwer"{
print("go to admin page")
} // 논리연산자
if id == "root" && password == "1234qwer"{
print("go to admin page")
}
else{
print("incorrect value") // 조건을 충족하지 않으면 출력되지 않음
}
let num = 123
if num >= 0{
print("positive or zero")
if num % 2 == 0 { // 상위 if 문이 만족 할 경우 실행
print("positive even")
}else if num % 2 == 1 {
print("positive odd")
}
}else{ // 최상위 if 문이 만족하지 않을 경우 실행
print("negative")
}
if num > 100 {
print("positive over 100")
}else if num > 10{
print("positive over 10")
}else if num > 0{
print("positive")
}
import Foundation
let num = 1
switch num {
case 1:
print("one")
case 2, 3: // 두가지의 경우를 한번에 사용 가능
print("two or three")
default:
break
}
let temperature = Int.random(in: -10 ... 30) // -10부터 30 까지의 랜덤 숫자를 저장(Int 내장함수)
switch temperature {
case ...10: // 범위로도 지정 가능
print("cold")
case 11...20:
print("cool")
case 21...27:
print("warm")
case 28...:
print("hot")
default:
break
}
let attempts = 10
switch attempts{
case ...9:
print("warning")
case 10:
print("locked")
fallthrough // 다음 케이스로 넘어가서 실행함(지금은 default로)
default:
print("send warning email")
}
import Foundation
func validate(id: String){
guard id.count >= 6 else { //조건 안에서 거짓일 떄의 실행되는 코드가 반드시 있어야함
return // 거짓일때의 코드
}
print("OK")
}
func validateUsingIf(id: String){
if id.count >= 6 {
if id.count <= 20{
print("OK")
}
}
}
validate(id: "short")
validate(id: "sdskjdfndslfj")
import UIKit
let hour = 12
hour < 12 ? "오전" : "오후"
hour < 12 ? 123 : 456 // 두번째와 세번째의 피연산자는 단위가 같아야함
import Foundation
for index in 1...10 { // 반복 횟수가 정해져 있을 때
print("hello \(index)") // ""안에서 변수값을 출력하기 위한 방법 : \()
}
for _ in 1...10 { // 언더스코어로 문자 생략. 가독성이 좋아짐 (와일드카드 패턴)
print("hi")
}
let power = 10
var result = 1
for _ in 1...power{
result *= 2
}
for num in stride(from: 0, through: 10, by: 2){ // 0 부터 10 까지 2씩 증가
print(num)
}
print("\n")
var sum = 0
for num in 1...10 {
sum += num
}
print(sum)
sum = 0
for num in stride(from: 1, to: 10, by: 1){ // 0..<10 과 같음
print(num)
sum+=num
}
print(sum)
for i in 2...9{
for j in 1...9{
print("\(i)*\(j)=\(i*j)")
}
print("\t")
}
import Foundation
var count = 5
while count > 0 { // 조건이 참일 때 계속
print("카운트다운: \(count)")
count -= 1
}
import Foundation
var num = 0
repeat {
print("num은 \(num)")
num += 1
} while num < 3 //무조건 한 번은 실행되는 do-while 스타일
import Foundation
let num = 2
switch num {
case 1...10:
print("begin block")
if !num.isMultiple(of: 2){ // num이 짝수가 아닐때
break
}
print("end block") // 짝수면 출력되고 switch문 종료
default:
break
}
print("Done")
for index in 1...10{
print(index)
if index > 1{
break
}
}
for i in 1...10 {
print("OUTER LOOP", i)
for j in 1...10 {
print("inner loop", j)
if j > 1 { // inerloop는 두번씩만 반복
break
}
}
}
import Foundation
for index in 1...10{
if index.isMultiple(of: 2){ // index가 짝수일때는 출력하지 않고 다음회차로 넘어간 후 반복
continue
}
print(index)
}
for i in 1...10 {
print("OUTER LOOP", i)
for j in 1...10{
if j.isMultiple(of: 2){
continue
}
print("inner loop", j)
}
}
import Foundation
func sayHello() {
print("hello")
}
sayHello()
func add() -> Int{ // 리턴타입 명시
return 1 + 2
}
print(add())
if add() == 3 {
sayHello()
}
let r = add()
print(r)
func printRandomEvenNumber(){ //랜덤 값이 짝수일 때 출력
let rnd = Int.random(in: 1...100)
if !rnd.isMultiple(of: 2){
return
}
print(rnd)
}
printRandomEvenNumber()
import Foundation // Parameter
func add(a:Int, b: Int) -> Int {
return a + b
}
let result = add(a:3, b:4)
print(result)
print(add(a:3, b:4))
func sayHello(to: String = "Stranger"){ // 기본 파라미터를 지정가능.
print("Hello, \(to)")
} // 파라미터의 자료형이 정해져서 함수의 자료형을 따로 표현하지 않아도 됨.
sayHello(to: "Swift") // 파라미터 전달
sayHello() // 파라미터를 전달 하지 않아서 기본값으로 출력
import Foundation //ArgumentLabel
func sayHello(name: String){
print("Hello, \(name)")
}
sayHello(name: "Swift")
func sayHello(to name: String){// to가 ArgumentLabel이됨.
print("Hello, \(name)")
}
sayHello(to: "Swift") // 파라미터 이름이 아닌 아규먼트 레이블 이름인 to를 사용.
func sayHello(_ name: String){// 아규먼트 레이블 생략
print("Hello, \(name)")
}
sayHello("Swift") // 아규먼트 레이블을 생략했기 때문에 파라미터 이름을 사용하지 않아도 됨.
공식문서