์๋ ํ์ธ์. ์ด๋ฒ์๋ Swift ์ปฌ๋ ์ ํ์ ์ ๋ํด ์์ธํ ์์๋ณด๊ฒ ์ต๋๋ค. Swift๋ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๊ธฐ ์ํ ์ธ ๊ฐ์ง ์ฃผ์ ์ปฌ๋ ์ ํ์ ์ ์ ๊ณตํฉ๋๋ค: ๋ฐฐ์ด(Array), ์งํฉ(Set), ๋์ ๋๋ฆฌ(Dictionary). ๊ฐ ํ์ ์ ํน์ฑ๊ณผ ์ฌ์ฉ๋ฒ์ ์์ ์ ํจ๊ป ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๐ ์ปฌ๋ ์ ํ์ ๊ฐ์
Swift์์ ์ ๊ณตํ๋ ์ธ ๊ฐ์ง ์ฃผ์ ์ปฌ๋ ์ ํ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ๋ฐฐ์ด(Array): ์์๊ฐ ์๋ ๊ฐ์ ์ปฌ๋ ์
- ์งํฉ(Set): ์์๊ฐ ์๊ณ ๊ณ ์ ํ ๊ฐ๋ง ํฌํจํ๋ ์ปฌ๋ ์
- ๋์ ๋๋ฆฌ(Dictionary): ํค-๊ฐ ์์ผ๋ก ์ด๋ฃจ์ด์ง ์์๊ฐ ์๋ ์ปฌ๋ ์
Swift์ ์ปฌ๋ ์ ํ์ ์ ์ ์ฅํ ์ ์๋ ๊ฐ์ ํ์ ๊ณผ ํค์ ๋ํด ํญ์ ๋ช ํํฉ๋๋ค. ์ด๋ ์ค์๋ก ์ปฌ๋ ์ ์ ์๋ชป๋ ํ์ ์ ๊ฐ์ ์ถ๊ฐํ ์ ์๋ค๋ ์๋ฏธ์ ๋๋ค.
์ปฌ๋ ์ ํ์ (Collection Types): ์ฌ๋ฌ ๊ฐ์ ํ๋์ ๋จ์๋ก ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ
์ปฌ๋ ์ ์ ๊ฐ๋ณ์ฑ
์ปฌ๋ ์ ์ ๋ณ์(var)์ ํ ๋นํ๋ฉด ๋ณ๊ฒฝ ๊ฐ๋ฅํ๊ณ , ์์(let)์ ํ ๋นํ๋ฉด ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅํฉ๋๋ค:
// ๋ณ๊ฒฝ ๊ฐ๋ฅํ ๋ฐฐ์ด
var mutableArray = [1, 2, 3]
mutableArray.append(4) // [1, 2, 3, 4]
// ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅํ ๋ฐฐ์ด
let immutableArray = [1, 2, 3]
// immutableArray.append(4) // ์ปดํ์ผ ์ค๋ฅ!
๊ฐ๋ณ์ฑ(Mutability): ๊ฐ์ฒด๊ฐ ์์ฑ๋ ํ ๋ด์ฉ์ ๋ณ๊ฒฝํ ์ ์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ ํน์ฑ
๐ ๋ฐฐ์ด (Arrays)
๋ฐฐ์ด์ ๊ฐ์ ํ์ ์ ๊ฐ์ ์์๋๋ก ์ ์ฅํ๋ ์ปฌ๋ ์ ์ ๋๋ค. ๋์ผํ ๊ฐ์ด ๋ฐฐ์ด ๋ด์์ ์ฌ๋ฌ ์์น์ ๋ํ๋ ์ ์์ต๋๋ค.
๋ฐฐ์ด ํ์ ๊ตฌ๋ฌธ
Swift ๋ฐฐ์ด์ ๋ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ํํํ ์ ์์ต๋๋ค:
- ์ ์ฒด ํ์: Array
- ์ถ์ฝ ํ์: [Element] (์ฃผ๋ก ์ฌ์ฉ๋จ)
๋น ๋ฐฐ์ด ์์ฑ
// ํ์
๋ช
์์ ํจ๊ป ๋น ๋ฐฐ์ด ๋ฆฌํฐ๋ด ์ฌ์ฉ
var someInts: [Int] = []
// ์ด๊ธฐํ ๊ตฌ๋ฌธ ์ฌ์ฉ
var someInts = [Int]()
๋ฐฐ์ด ๋ฆฌํฐ๋ด(Array Literal): ๋๊ดํธ([])๋ก ๋๋ฌ์ธ์ธ ์ผํ๋ก ๊ตฌ๋ถ๋ ๊ฐ ๋ชฉ๋ก์ผ๋ก, ๋ฐฐ์ด์ ์ด๊ธฐํํ๋ ๋ฐฉ๋ฒ
๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋ฐฐ์ด ์์ฑ
// 0.0์ด 3๋ฒ ๋ฐ๋ณต๋๋ ๋ฐฐ์ด ์์ฑ
var threeDoubles = Array(repeating: 0.0, count: 3)
// [0.0, 0.0, 0.0]
๋ ๋ฐฐ์ด ํฉ์น๊ธฐ
let firstArray = [1, 2, 3]
let secondArray = [4, 5, 6]
let combinedArray = firstArray + secondArray
// [1, 2, 3, 4, 5, 6]
๋ฐฐ์ด ๋ฆฌํฐ๋ด๋ก ๋ฐฐ์ด ์์ฑ
var shoppingList: [String] = ["Eggs", "Milk"]
// ํ์
์ถ๋ก ์ ์ฌ์ฉํ ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ
var shoppingList = ["Eggs", "Milk"]
๋ฐฐ์ด ์ ๊ทผ ๋ฐ ์์
// ๋ฐฐ์ด์ ์์ ์ ํ์ธ
print("The shopping list contains \(shoppingList.count) items.")
// ๋ฐฐ์ด์ด ๋น์ด์๋์ง ํ์ธ
if shoppingList.isEmpty {
print("The shopping list is empty.")
}
// ๋ฐฐ์ด์ ์์ ์ถ๊ฐ
shoppingList.append("Flour")
shoppingList += ["Baking Powder"]
shoppingList += ["Chocolate", "Cheese", "Butter"]
// ์๋ธ์คํฌ๋ฆฝํธ๋ก ์์ ์ ๊ทผ
var firstItem = shoppingList[0] // "Eggs"
// ์๋ธ์คํฌ๋ฆฝํธ๋ก ์์ ๋ณ๊ฒฝ
shoppingList[0] = "Six eggs"
// ๋ฒ์๋ก ์ฌ๋ฌ ์์ ๋ณ๊ฒฝ
shoppingList[4...6] = ["Bananas", "Apples"]
// ํน์ ์์น์ ์์ ์ฝ์
shoppingList.insert("Maple Syrup", at: 0)
// ์์ ์ญ์
let mapleSyrup = shoppingList.remove(at: 0)
// ๋ง์ง๋ง ์์ ์ญ์
let apples = shoppingList.removeLast()
์๋ธ์คํฌ๋ฆฝํธ(Subscript): ๋ฐฐ์ด์ ํน์ ์์น์ ์๋ ์์์ ์ ๊ทผํ๊ธฐ ์ํด ๋ฐฐ์ด ์ด๋ฆ ๋ค์ ๋๊ดํธ ์์ ์ธ๋ฑ์ค๋ฅผ ์ง์ ํ๋ ๋ฌธ๋ฒ
์ธ๋ฑ์ค(Index): ๋ฐฐ์ด ๋ด ์์์ ์์น๋ฅผ ๋ํ๋ด๋ ์ ์๊ฐ์ผ๋ก, Swift์์๋ 0๋ถํฐ ์์
๋ฐฐ์ด ๋ฐ๋ณต
// ๋ชจ๋ ์์ ์ํ
for item in shoppingList {
print(item)
}
// ์ธ๋ฑ์ค์ ๊ฐ ํจ๊ป ์ํ
for (index, value) in shoppingList.enumerated() {
print("Item \(index + 1): \(value)")
}
enumerated(): ๋ฐฐ์ด์ ๊ฐ ์์์ ๋ํด (์ธ๋ฑ์ค, ๊ฐ) ์์ ํํ๋ก ๋ฐํํ๋ ๋ฉ์๋
๐ ์งํฉ (Sets)
์งํฉ์ ์์๊ฐ ์๊ณ ๊ณ ์ ํ ๊ฐ๋ง ์ ์ฅํ๋ ์ปฌ๋ ์ ์ ๋๋ค. ํญ๋ชฉ์ ์์๊ฐ ์ค์ํ์ง ์๊ฑฐ๋ ์ค๋ณต์ ํ์ฉํ์ง ์์์ผ ํ ๋ ์ฌ์ฉํฉ๋๋ค.
์งํฉ ํ์ ๊ตฌ๋ฌธ
์งํฉ์ Set
ํด์ ๊ฐ๋ฅํ ํ์
์งํฉ์ ์ ์ฅ๋๋ ํ์ ์ ๋ฐ๋์ Hashable ํ๋กํ ์ฝ์ ์ค์ํด์ผ ํฉ๋๋ค. Swift์ ๊ธฐ๋ณธ ํ์ (String, Int, Double, Bool)์ ๋ชจ๋ ํด์ ๊ฐ๋ฅํฉ๋๋ค.
ํด์ ๊ฐ๋ฅ(Hashable): ๊ฐ์ ๊ณ ์ ํ ์ ์ ํด์๊ฐ์ผ๋ก ๋ณํํ ์ ์๋ ํ์ ์ ํน์ฑ
ํด์๊ฐ(Hash Value): ๋ฐ์ดํฐ๋ฅผ ๊ณ ์ ๊ธธ์ด์ ๊ฐ์ผ๋ก ๋ณํํ ๊ฒฐ๊ณผ๋ก, ์งํฉ์ด๋ ๋์ ๋๋ฆฌ์์ ๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ๋ ๋ฐ ์ฌ์ฉ
๋น ์งํฉ ์์ฑ
var letters = Set<Character>()
๋ฐฐ์ด ๋ฆฌํฐ๋ด๋ก ์งํฉ ์์ฑ
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// ํ์
๋ช
์๊ฐ ์์ผ๋ฉด ๊ฐ๋จํ ์์ฑ ๊ฐ๋ฅ
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
์งํฉ ์ ๊ทผ ๋ฐ ์์
// ์งํฉ์ ์์ ์ ํ์ธ
print("I have \(favoriteGenres.count) favorite music genres.")
// ์งํฉ์ด ๋น์ด์๋์ง ํ์ธ
if favoriteGenres.isEmpty {
print("I have no favorite music genres.")
}
// ์งํฉ์ ์์ ์ถ๊ฐ
favoriteGenres.insert("Jazz")
// ์งํฉ์์ ์์ ์ ๊ฑฐ
if let removedGenre = favoriteGenres.remove("Rock") {
print("\(removedGenre) has been removed.")
}
// ์งํฉ์ ํน์ ์์๊ฐ ํฌํจ๋์ด ์๋์ง ํ์ธ
if favoriteGenres.contains("Funk") {
print("I like Funk.")
}
์งํฉ ๋ฐ๋ณต
// ์์ ์ํ (์์๋ ๋ณด์ฅ๋์ง ์์)
for genre in favoriteGenres {
print("\(genre)")
}
// ์ ๋ ฌ๋ ์์๋ก ์ํ
for genre in favoriteGenres.sorted() {
print("\(genre)")
}
์งํฉ ์ฐ์ฐ
์งํฉ์ ์ํ์ ์งํฉ ์ด๋ก ๊ณผ ๋์ผํ ์ฐ์ฐ์ ์ ๊ณตํฉ๋๋ค:
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let primeDigits: Set = [2, 3, 5, 7]
// ํฉ์งํฉ: ๋ ์งํฉ์ ๋ชจ๋ ๊ฐ์ ํฌํจ
oddDigits.union(evenDigits) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// ๊ต์งํฉ: ๋ ์งํฉ์ ๊ณตํต์ผ๋ก ํฌํจ๋ ๊ฐ๋ง ํฌํจ
oddDigits.intersection(primeDigits) // [3, 5, 7]
// ์ฐจ์งํฉ: ๋ค๋ฅธ ์งํฉ์ ํฌํจ๋์ง ์์ ๊ฐ๋ง ํฌํจ
oddDigits.subtracting(primeDigits) // [1, 9]
// ๋์นญ ์ฐจ์งํฉ: ํ์ชฝ ์งํฉ์๋ง ์๋ ๊ฐ์ ํฌํจ
oddDigits.symmetricDifference(primeDigits) // [1, 2, 9]
ํฉ์งํฉ(Union): ๋ ์งํฉ์ ๋ชจ๋ ์์๋ฅผ ํฌํจํ๋ ์ ์งํฉ
๊ต์งํฉ(Intersection): ๋ ์งํฉ์ ๊ณตํต์ผ๋ก ํฌํจ๋ ์์๋ง ํฌํจํ๋ ์ ์งํฉ
์ฐจ์งํฉ(Subtraction): ํ ์งํฉ์์ ๋ค๋ฅธ ์งํฉ์ ํฌํจ๋ ์์๋ฅผ ์ ์ธํ ์ ์งํฉ
๋์นญ์ฐจ์งํฉ(Symmetric Difference): ๋ ์งํฉ ์ค ํ์ชฝ์๋ง ์๋ ์์๋ฅผ ํฌํจํ๋ ์ ์งํฉ
์งํฉ ๊ด๊ณ ์ฐ์ฐ
let houseAnimals: Set = ["๐ถ", "๐ฑ"]
let farmAnimals: Set = ["๐ฎ", "๐", "๐", "๐ถ", "๐ฑ"]
let cityAnimals: Set = ["๐ฆ", "๐ญ"]
// ๋ถ๋ถ์งํฉ ์ฌ๋ถ ํ์ธ
houseAnimals.isSubset(of: farmAnimals) // true
// ์์์งํฉ ์ฌ๋ถ ํ์ธ
farmAnimals.isSuperset(of: houseAnimals) // true
// ์๋ก์ ์ฌ๋ถ ํ์ธ (๊ณตํต ์์๊ฐ ์๋์ง)
farmAnimals.isDisjoint(with: cityAnimals) // true
๋ถ๋ถ์งํฉ(Subset): ํ ์งํฉ์ ๋ชจ๋ ์์๊ฐ ๋ค๋ฅธ ์งํฉ์ ํฌํจ๋๋ ๊ด๊ณ
์์์งํฉ(Superset): ํ ์งํฉ์ด ๋ค๋ฅธ ์งํฉ์ ๋ชจ๋ ์์๋ฅผ ํฌํจํ๋ ๊ด๊ณ
์๋ก์ ์งํฉ(Disjoint Sets): ๊ณตํต ์์๊ฐ ์๋ ๋ ์งํฉ์ ๊ด๊ณ
๐ ๋์ ๋๋ฆฌ (Dictionaries)
๋์ ๋๋ฆฌ๋ ํค-๊ฐ ์์ ์ ์ฅํ๋ ์ปฌ๋ ์ ์ผ๋ก, ๊ฐ ๊ฐ์ ๊ณ ์ ํ ํค์ ์ฐ๊ฒฐ๋ฉ๋๋ค. ํค๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ์ ์ ์์ต๋๋ค.
๋์ ๋๋ฆฌ ํ์ ๊ตฌ๋ฌธ
Swift ๋์ ๋๋ฆฌ๋ ๋ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ํํํ ์ ์์ต๋๋ค:
- ์ ์ฒด ํ์: Dictionary<Key, Value>
- ์ถ์ฝ ํ์: [Key: Value] (์ฃผ๋ก ์ฌ์ฉ๋จ)
ํด์ ๊ฐ๋ฅํ ํค
๋์ ๋๋ฆฌ์ ํค ํ์ ์ ๋ฐ๋์ Hashable ํ๋กํ ์ฝ์ ์ค์ํด์ผ ํฉ๋๋ค.
๋น ๋์ ๋๋ฆฌ ์์ฑ
// ํ์
์ ๋ช
์ํ์ฌ ๋น ๋์
๋๋ฆฌ ์์ฑ
var namesOfIntegers = [Int: String]()
// ํ์
์ด ์ด๋ฏธ ๋ช
์๋ ๊ฒฝ์ฐ ๊ฐ๋จํ ๋ฐฉ๋ฒ
namesOfIntegers = [:]
๋์ ๋๋ฆฌ ๋ฆฌํฐ๋ด๋ก ๋์ ๋๋ฆฌ ์์ฑ
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
// ํ์
์ถ๋ก ์ฌ์ฉ
var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
๋์ ๋๋ฆฌ ๋ฆฌํฐ๋ด(Dictionary Literal): ๋๊ดํธ([]) ์์ ์ฝ๋ก (:)์ผ๋ก ๊ตฌ๋ถ๋ ํค-๊ฐ ์๋ค๋ก, ๋์ ๋๋ฆฌ๋ฅผ ์ด๊ธฐํํ๋ ๋ฐฉ๋ฒ
๋์ ๋๋ฆฌ ์ ๊ทผ ๋ฐ ์์
// ๋์
๋๋ฆฌ์ ํญ๋ชฉ ์ ํ์ธ
print("The airports dictionary contains \(airports.count) items.")
// ๋์
๋๋ฆฌ๊ฐ ๋น์ด์๋์ง ํ์ธ
if airports.isEmpty {
print("The airports dictionary is empty.")
}
// ๋์
๋๋ฆฌ์ ํญ๋ชฉ ์ถ๊ฐ
airports["LHR"] = "London"
// ๋์
๋๋ฆฌ์ ๊ฐ ๋ณ๊ฒฝ
airports["LHR"] = "London Heathrow"
// updateValue ๋ฉ์๋๋ก ๊ฐ ์
๋ฐ์ดํธ (์ด์ ๊ฐ ๋ฐํ)
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
print("The old value was \(oldValue).")
}
// ๋์
๋๋ฆฌ์์ ๊ฐ ๊ฐ์ ธ์ค๊ธฐ
if let airportName = airports["DUB"] {
print("The name of the airport is \(airportName).")
} else {
print("That airport is not in the airports dictionary.")
}
// ๋์
๋๋ฆฌ์์ ํญ๋ชฉ ์ ๊ฑฐ (nil ํ ๋น)
airports["APL"] = "Apple International"
airports["APL"] = nil // ์ ๊ฑฐ๋จ
// removeValue ๋ฉ์๋๋ก ํญ๋ชฉ ์ ๊ฑฐ (์ ๊ฑฐ๋ ๊ฐ ๋ฐํ)
if let removedValue = airports.removeValue(forKey: "DUB") {
print("The removed airport's name is \(removedValue).")
}
ํค-๊ฐ ์(Key-Value Pair): ๋์ ๋๋ฆฌ์์ ๊ฐ์ ์ ๊ทผํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๊ณ ์ ์๋ณ์(ํค)์ ๊ทธ์ ์ฐ๊ฒฐ๋ ๋ฐ์ดํฐ(๊ฐ)์ ์กฐํฉ
๋์ ๋๋ฆฌ ๋ฐ๋ณต
// ํค-๊ฐ ์ ์ํ
for (airportCode, airportName) in airports {
print("\(airportCode): \(airportName)")
}
// ํค๋ง ์ํ
for airportCode in airports.keys {
print("Airport code: \(airportCode)")
}
// ๊ฐ๋ง ์ํ
for airportName in airports.values {
print("Airport name: \(airportName)")
}
// ํค๋ ๊ฐ์ ๋ฐฐ์ด๋ก ๋ณํ
let airportCodes = [String](airports.keys)
let airportNames = [String](airports.values)
// ์ ๋ ฌ๋ ์์๋ก ์ํ
for airportCode in airports.keys.sorted() {
print("Airport code: \(airportCode)")
}
keys: ๋์ ๋๋ฆฌ์ ๋ชจ๋ ํค๋ฅผ ํฌํจํ๋ ์ปฌ๋ ์ ์ ์ ๊ทผํ๋ ํ๋กํผํฐ
values: ๋์ ๋๋ฆฌ์ ๋ชจ๋ ๊ฐ์ ํฌํจํ๋ ์ปฌ๋ ์ ์ ์ ๊ทผํ๋ ํ๋กํผํฐ
๐ ์ ๋ฆฌ
Swift์ ์ธ ๊ฐ์ง ์ฃผ์ ์ปฌ๋ ์ ํ์ ์ ๊ฐ๊ฐ ๋ค๋ฅธ ์ํฉ์์ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋ฉ๋๋ค:
- ๋ฐฐ์ด(Array): ์์๊ฐ ์ค์ํ๊ฑฐ๋ ๋์ผํ ํญ๋ชฉ์ด ์ฌ๋ฌ ๋ฒ ๋ํ๋ ์ ์์ ๋ ์ฌ์ฉ
- ์งํฉ(Set): ์ค๋ณต ์์ด ๊ณ ์ ํ ๊ฐ๋ง ํ์ํ๊ณ ์์๊ฐ ์ค์ํ์ง ์์ ๋ ์ฌ์ฉ
- ๋์ ๋๋ฆฌ(Dictionary): ํค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ์ ๋น ๋ฅด๊ฒ ๊ฒ์ํด์ผ ํ ๋ ์ฌ์ฉ
๊ฐ ์ปฌ๋ ์ ํ์ ์ ํ์ ์์ ์ฑ์ ๋ณด์ฅํ๋ฏ๋ก, ํญ์ ์ ์๋ ํ์ ์ ๊ฐ๋ง ์ ์ฅํ๊ณ ๊ฒ์ํ ์ ์์ต๋๋ค. ์ด๋ Swift ์ฝ๋์ ์์ ์ฑ๊ณผ ์์ธก ๊ฐ๋ฅ์ฑ์ ๋์ด๋ ๋ฐ ํฐ ๋์์ด ๋ฉ๋๋ค.
'๐ฅ Bread Basics > Swift' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ์ด๊ฑฐํ (Enumerations) (0) | 2025.04.11 |
---|---|
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ํด๋ก์ (Closures) (0) | 2025.04.11 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ํจ์ (Functions) (0) | 2025.04.11 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ์ ์ด ํ๋ฆ (Control Flow) (0) | 2025.04.10 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ๋ฌธ์์ด๊ณผ ๋ฌธ์ (Strings and Characters) (0) | 2025.04.10 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ๊ธฐ๋ณธ ์ฐ์ฐ์ (Basic Operators) (0) | 2025.04.10 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ๊ธฐ๋ณธ(The Basics)(2/2) (0) | 2025.04.10 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ๊ธฐ๋ณธ(The Basics)(1/2) (0) | 2025.04.10 |