Shape
νλ‘ν μ½μ μꡬμ¬νμΈ draw()
ν¨μ.protocol Shape {
func draw() -> String
}
struct Triangle: Shape {
var size: Int
func draw() -> String {
var result: [String] = []
for length in 1...size {
result.append(String(repeating: "*", count: length))
}
return result.joined(separator: "\n")
}
}
let smallTriangle = Triangle(size: 3)
print(smallTriangle.draw())
// *
// **
// ***
// μμ μ½μμ μμ§μΌλ‘ λ€μ§λ μ½λλ₯Ό ꡬν.
// Triangle μ λ£μΌλ©΄ FlippedShape<Triangle> μ΄ μμ±λ¨.
struct FlippedShape<T: Shape>: Shape {
var shape: T
func draw() -> String {
let lines = shape.draw().split(separator: "\n")
return lines.reversed().joined(separator: "\n")
}
}
let flippedTriangle = FlippedShape(shape: smallTriangle)
print(flippedTriangle.draw())
// ***
// **
// *
// μμ λ μ½λλ₯Ό κ²°ν©
// μμ Triangle μ λ£μΌλ©΄?
// JoinedShape<FlippedShape<Triangle>, Triangle> μ΄λ° νμ
μ΄ μμ±λ¨.
struct JoinedShape<T: Shape, U: Shape>: Shape {
var top: T
var bottom: U
func draw() -> String {
return top.draw() + "\n" + bottom.draw()
}
}
let joinedTriangles = JoinedShape(top: smallTriangle, bottom: flippedTriangle)
print(joinedTriangles.draw())
// *
// **
// ***
// ***
// **
// *
JoinedShape<FlippedShape<Triangle>, Triangle>
μ΄λ°κ±Έ λ°ν νμ
μΌλ‘ μ°κ³ μΆμ§λ μλ€...JoinedShape
μ FlippedShape
μ κ°μ λνΌ νμ
μ λͺ¨λμ μ¬μ©μμκ²λ μ€μνμ§ μμ μ 보μ΄λ―λ‘ νμλμ§ μμμΌ ν¨ -> μ°λ¦¬μκ² νμν건 κ·Έκ² Shape
λΌλ κ² λΏ.Stack<Int>
(Intλ Equatable) μ΄λ κ² Element κ° μ ν΄μ§κ² λλλ°,some Equatable
λ‘ λ¦¬ν΄νκ³ μΆλ€λ λ».struct Stack<Element: Equatable> {
var list: [Element]
mutating func append(_ element: Element) {
list.append(element)
}
// Generic
mutating func pop() -> Element {
return list.remove(at: list.count - 1)
}
// Opaque Type
mutating func pop() -> some Equatable {
return list.remove(at: list.count - 1)
}
}
// generic
func max<T>(_ x: T, _ y: T) -> T where T: Comparable { ... }
νμ§λ§ Opaque Type μ κ²½μ°?
some
ν€μλ μ¬μ©.struct Square: Shape {
var size: Int
func draw() -> String {
// λͺ¨μμ κΈ°λ³Έ νμ
μ΄ λμ§ λͺ¨λ₯΄κ² λλ°, λ°νμ ν μ μμ.
let line = String(repeating: "*", count: size)
let result = Array<String>(repeating: line, count: size)
return result.joined(separator: "\n")
}
}
// κ·Έλμ some Shape λΌλ κ°μΌλ‘ λ°ν.
// JoinedShape<Triangle, FilppedShape<Triangle>> μ²λΌ νμ
μ μ ν΄μ€ νμκ° μλ€.
// <T: Shape> -> T κ° μλλ°λ, some Shape λΌλ κ°μΌλ‘ λ°νμ΄ κ°λ₯ν κ².
func makeTrapezoid() -> some Shape {
let top = Triangle(size: 2)
let middle = Square(size: 2)
let bottom = FlippedShape(shape: top)
let trapezoid = JoinedShape(
top: top,
bottom: JoinedShape(top: middle, bottom: bottom)
)
return trapezoid
}
let trapezoid = makeTrapezoid()
print(trapezoid.draw())
// *
// **
// **
// **
// **
// *
func flip<T: Shape>(_ shape: T) -> some Shape {
return FlippedShape(shape: shape)
}
func join<T: Shape, U: Shape>(_ top: T, _ bottom: U) -> some Shape {
JoinedShape(top: top, bottom: bottom)
}
let opaqueJoinedTriangles = join(smallTriangle, flip(smallTriangle))
print(opaqueJoinedTriangles.draw())
// *
// **
// ***
// ***
// **
// *
filp
join
ν¨μλ‘ λνν΄μ FlippedShape
, JoinedShape
κ° μ΄λ€ νμ
μΈμ§ λλ¬λμ§ μκ² νλ€.some Shape
μΌ λΏ.func invalidFlip<T: Shape>(_ shape: T) -> some Shape {
if shape is Square {
return shape // Error: return types don't match
}
return FlippedShape(shape: shape) // Error: return types don't match
}
struct FlippedShape<T: Shape>: Shape {
var shape: T
func draw() -> String {
if shape is Square {
return shape.draw() // μ΄λ κ². μ¬μ©νμ.
}
let lines = shape.draw().split(separator: "\n")
return lines.reversed().joined(separator: "\n")
}
}
// λ°νκ°μ κΈ°λ³Έ νμ
μ Array<Shape> λ‘ μ€μ .
// λμ Shape κ° μμλ‘ λ€μ΄κ°μΌν¨.
func `repeat`<T: Shape>(shape: T, count: Int) -> some Collection {
return Array<T>(repeating: shape, count: count)
}
var f1: CarFactory = TeslaFactory()
// ERROR : Protocol 'CarFactory' can be only used as a generic constraint ...
var f1: some CarFactory = TeslaFactory()
print(f1.produce())
// OK
νμ
μ 체μ±
μ μ μ§νλμ§ μ¬λΆλ‘ κ°λ¦°λ€.// νλ‘ν μ½λ‘ ꡬνν μμ ν¨μ.
// Shape νλ‘ν μ½μ λ°λ₯΄λ μ¬λ¬ νμ
μ κ°μ λ°νν μ μλ€.
func protoFlip<T: Shape>(_ shape: T) -> Shape {
if shape is Square {
return shape // Square return κ°λ₯.
}
return FlippedShape(shape: shape)
}
let protoFlippedTriangle = protoFlip(smallTriangle)
let sameThing = protoFlip(smallTriangle)
protoFlippedTriangle == sameThing // Error : == μ΄ κ΅¬νμ΄ μλμ΄ μμ.
protoFlip(protoFlip(smallTriangle)) // Error : ν λ² λ€μ§μκ² μ ν¨ν μΈμκ° μλ.
// Generic T: Shape μλ Shape λ₯Ό ꡬνν ꡬ체μ μΈ νμ
λ§μ΄ κ° μ μλλ°,
// Shape κ° λ°ν νμ
μ΄λ―λ‘ Shape νλ‘ν μ½ μ체λ₯Ό μΈμλ‘ λ£μ κ²μ΄ λ¨.
protoFlip(protoFlippedTriangle as! FlippedShape<Triangle>)
// μ νν νμ
μΌλ‘ downcast νλ©΄ κ°λ₯ν¨.
protocol Container {
associatedtype Item
// Item μ΄λΌλ associatedtype μ΄ μμ΄μ Container λ₯Ό λ°ννμ
μΌλ‘ μ¬μ©ν μ μμ.
// Item μ΄ μ΄λ€ νμ
μΈμ§λ₯Ό λͺ¨λ₯΄λκΉ.
// λ°ν μ μ½ μ‘°κ±΄μΌλ‘λ μ¬μ©μ΄ μλ¨.
var count: Int { get }
subscript(i: Int) -> Item { get }
}
extension Array: Container { }
// Error: Protocol with associated types can't be used as a return type.
func makeProtocolContainer<T>(item: T) -> Container {
return [item]
}
// Error: Not enough information to infer C.
func makeProtocolContainer<T, C: Container>(item: T) -> C {
return [item]
}
// κ·ΈμΉλ§ μ΄λ κ² some μ λΆμ¬μ λΆν¬λͺ
ν νμ
μ 보λ΄μ£Όλ©΄?
// 컨ν
μ΄λλ₯Ό λ°ννλ, νμ
μ§μ μ κ±°λΆνκ² λλ―λ‘ μ°κ΄ νμ
μ΄ μλ protocol λ°νμ΄ κ°λ₯ν΄μ§λ€.
func makeOpaqueContainer<T>(item: T) -> some Container {
return [item]
}
let opaqueContainer = makeOpaqueContainer(item: 12)
let twelve = opaqueContainer[0]
print(type(of: twelve)) // Prints "Int" : νμ
μΆλ‘ κ°λ₯.
func getComparable() -> Comparable { // error : νλ‘ν μ½μ λ°λ₯΄λ νμ
μ λ°νν μκ° μμ.
return 1
}
// κ·Έλμ μλμ²λΌ Generic μ ν΅ν΄μ Comparable μ λ°λ₯΄λ μ΄λ€ νμ
μ μ¬μ©νλ€κ³ λͺ
μν΄μΌ νμ.
// κ·Έλ¬λ©΄ ν¨μ μΈλΆμμ μ΄ νμ
μ΄ λμ§... λͺ
μκ° νμν¨.
func getComparable<T: Comparable>() -> T {
return 1 as! T
}
func getComparable<T>() -> T
where T: Comparable {
return 1 as! T
}
func getComparable() -> some Comparable {
return 1
}
func getComparable() -> some Comparable {
if true { return 1 }
else { return "oh my god" }
}
https://sanichdaniel.tistory.com/16
<T: Equtable>
where
ν€μλλ‘ μ§μ ν΄μ€ μ μμμ. Array<Int>
func getComparable<T>() -> T
where T: Comparable {
return 1
}
: some Comparable
λ₯Ό μ¬μ©νλ€.Comparable
λ§μ΄ λ°νλμ΄μΌ ν¨.