https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html
https://docs.swift.org/swift-book/ReferenceManual/Types.html#grammar_tuple-type
import UIKit
class ViewController: UIViewController {
private var calculator = CalculatorLogic() //setNumber를 통해 변경하기도 하므로 var로 선언
@IBOutlet weak var displayLabel: UILabel!
//private를 사용해 클래스 안에서만 사용될 수 있도록 한다
private var isFinishedTypingNumber: Bool = true
// 💥 computed property
private var displayValue: Double {
get {
//if let을 쓴 경우 더블로 캐스팅하지 못하면 그냥 스킵되기 때문에
//에러메시지를 보기 위해 guard let을 사용했다
guard let number = Double(displayLabel.text!) else {
fatalError("Cannot Convert display label text to a Double")
}
return number
}
set {
displayLabel.text = String(newValue)
}
}
@IBAction func calcButtonPressed(_ sender: UIButton) {
//초기 텍스트 0을 지우기 위해 사용
isFinishedTypingNumber = true
calculator.setNumber(displayValue)
if let calcMethod = sender.currentTitle {
if let result = calculator.calculate(symbol: calcMethod) {
displayValue = result
}
}
}
@IBAction func numButtonPressed(_ sender: UIButton) {
if let numValue = sender.currentTitle {
//처음 숫자를 입력하면 0으로 대체되게 하기 위해 Bool 사용
if isFinishedTypingNumber {
displayLabel.text = numValue
isFinishedTypingNumber = false
//숫자 입력한 적이 있을 때
} else {
// 3.2.6 과 같은 입력 방지하기
if numValue == "." {
let isInt = floor(displayValue) == displayValue
if !isInt { // 소수점(decimal place)이 이미 있으면 더이상 .이 눌리지 않는다
return
}
}
displayLabel.text = displayLabel.text! + numValue
}
}
}
}
import Foundation
struct CalculatorLogic {
//global variable의 경우는 외부에서 변경하지 못하도록 private으로 사용하는 것이 일반적이다
private var number: Double?
private var intermediateCalculation: (n1: Double, calcMethod: String)?
mutating func setNumber(_ number: Double) {
self.number = number
}
mutating func calculate(symbol: String) -> Double? {
if let n = number {
if symbol == "+/-" {
return n * -1
} else if symbol == "AC" {
return 0
} else if symbol == "%" {
return n * 0.01
} else if symbol == "=" {
performTwoNumberCalculation(n2: n)
} else {
intermediateCalculation = (n1: n, calcMethod: symbol)
}
}
return nil
}
func performTwoNumberCalculation(n2: Double) -> Double? {
if let n1 = intermediateCalculation?.n1, let operation = intermediateCalculation?.calcMethod {
switch operation {
case "+":
return n1 + n2
case "-":
return n1 - n2
case "×":
return n1 * n2
case "÷":
return n1 / n2
default:
fatalError("The operation passed in does not match any of the cases")
}
}
return nil
}
}
계산기 만들기...
정말 어렵다...
뭔가 새롭게 알게 된 점은
return nil이 포함된 경우 return? 이런식으로 하면 된다는 것이다
Structs | Classes |
---|---|
Simpler | Has inheritance |
Faster | Works with objective-C code |
값 타입 | 참조타입 |
스택 | 힙 |
init 불필요 | init 필요 |
Deep Copies | |
True immutability | |
No memory leaks |
import Foundation
class Classhero {
var name: String
var universe: String
init(name: String, universe: String) {
self.name = name
self.universe = universe
}
}
import Foundation
struct Structhero {
var name: String
var universe: String
//값을 변경하려면 mutating 키워드를 써줘야 한다
mutating func reverseName() {
self.name = String(self.name.reversed())
}
}
import Foundation
//MARK: - class
let hero = Classhero(name: "Iron Man", universe: "Marvle")
hero.name = "Cat woman" //가능한 이유는 class안의 name이 var로 선언되어 있기 때문이다
var anotherMarvleHero = hero
anotherMarvleHero.name = "The Hulk"
print(hero.name)
print(anotherMarvleHero.name)
//MARK: - struct
var heroS = Structhero(name: "Iron Man", universe: "Marvle")
//heroS.name = "Cat" //struct는 immutable하기 때문에 오류가 발생한다 (값을 바꾼다는 것은 copy해서 또 생성하는 것을 의미하기 때문이다)
var anotherMarvleHeroS = heroS
anotherMarvleHeroS.name = "The Hulk"
print(heroS.name)
print(anotherMarvleHeroS.name)
//let heroS이기 때문에 변경할 수 없다 -> var로 바꿔준다
heroS.reverseName()
print(heroS.name)
https://docs.swift.org/swift-book/ReferenceManual/Types.html#grammar_tuple-type
let tuple1 = ("A", 12)
let tuple2 = (name: "B", age: 13)
let tuple3: (name: String, age: Int)
tuple3 = (name: "C", age: 21)
print(tuple1.0) //A
print(tuple2.name) //B
print(tuple3.name, tuple3.age) //C 21
command + option + ←
코드 뭉텅이 접기
Male donkey + female horse = mule