32. var body: some View {1
VStack {2
Image("SwiftUI")
.resizable()
.scaledToFit()
Text("Hello SwiftUI!")
.foregroundColor(.white)
.background(Color.black)
}.padding()
}3
Opaque type
33. func genericFunction<T: Animal>(_ animal: T) {
... // Callee - abstracted type
}
// T == Dog, Caller pick the type
genericFunction(Dog())
Abstracted type - Generic
// T == Cat
genericFunction(Cat())
34. func opaqueTypeFunction() -> some Animal {
Dog() // Callee pick the type
}
// Caller - abstracted type
let animal: some Animal = opaqueTypeFunction()
Abstracted type - Opaque type
38. Type identity
func genericFunc<T: Equatable>(
lhs: T, rhs: T
) -> Bool {
lhs == rhs // Same generic type T
}
// Caller pick the type
genericFunction(lhs: "Swift", rhs: "UI")
39. Type identity
func opaqueTypeFunc() -> some Equatable {
.random() ? "Swift" : 5.1
}
func opaqueTypeFunc() -> some Equatable {
// Callee pick the type
// Same return type
.random() ? "Swift" : "UI"
}
40. var body: some View {
.random()
? Rectangle()
: Circle()
}
SwiftUI
var body: some View {
.random()
? AnyView(Rectangle())
: AnyView(Circle())
}
41. • Hiding type information
Opaque Result TypesSE-0244
• Preserving type information
• Reverse generic
63. struct SomeType {
var someValue = 0
lazy var someLazyValue = self.someValue + 1
}1
lazy
64. struct SomeType {
var someValue = 0
lazy var someLazyValue = self.someValue + 1
lazy var anotherLazyValue = self.someValue * 2
}1
lazy
65. Boilerplate
var isLoggedIn: Bool {
get {
UserDefaults.standard.bool(forKey: "IS_LOGGED_IN")
}
set {
UserDefaults.standard.set(newValue, forKey: "IS_LOGGED_IN")
}
}
66. Boilerplate
var isLoggedIn: Bool {
get {
UserDefaults.standard.bool(forKey: "IS_LOGGED_IN")
}
set {
UserDefaults.standard.set(newValue, forKey: "IS_LOGGED_IN")
}
}
var isFirstLogin: Bool {
get {
UserDefaults.standard.bool(forKey: "IS_FIRST_LOGIN")
}
set {
UserDefaults.standard.set(newValue, forKey: "IS_FIRST_LOGIN")
}
}
67. Wrapper Type
@propertyWrapper
struct UserDefault<Value> {
let key: String
var wrappedValue: Value? {
get {
UserDefaults.standard.object(forKey: key) as? Value
}
set {
UserDefaults.standard.set(newValue, forKey: key)
}
}
}
68. Custom attribute
struct User {
@UserDefault(key: "IS_LOGGED_IN")
var isLoggedIn: Bool
@UserDefault(key: "IS_FIRST_LOGIN")
var isFirstLogin: Bool
}
69. Custom attribute
struct User {
@UserDefault(key: "IS_LOGGED_IN")
var isLoggedIn: Bool
@UserDefault(key: "IS_FIRST_LOGIN")
var isFirstLogin: Bool
}
var user = User()
user.isLoggedIn = true
user.isFirstLogin = false
print(user.isLoggedIn ?? false)
print(user.isFirstLogin ?? true)