Custom Expressible Protocol To Implement Implicit Construction In Swift
Asked Answered
N

1

10

AFAIK, Swift class can be assigned by literal value by conform to ExpressibleBy*Literal .

For example, class A can be assigned by Int like this, which is similar to implicit construction in C++

class A : ExpressibleByIntegerLiteral {
    typealias IntegerLiteralType = Int

    required init(integerLiteral value: A.IntegerLiteralType) {
    }
}

var a: A = 1

Now, can I extended ExpressibleBy* protocol to any my custom type ?

protocol ExpressibleByMyTypeLiteral {
    associatedtype MyType

    init(literal value: Self.MyType) 
}

class B {
}

class A : ExpressibleByIntegerLiteral, ExpressibleByMyTypeLiteral {
    //ExpressibleByIntegerLiteral
    typealias IntegerLiteralType = Int

    required init(integerLiteral value: A.IntegerLiteralType) {
    }

    //ExpressibleByMyTypeLiteral
    typealias MyType = B

    required init(literal value: A.MyType) {
    } 
}

var a: A = 1
var aMyType: A = B() //Compiler Error: Cannot convert value of 'B' to specified type 'A'
Nievelt answered 12/10, 2017 at 3:35 Comment(2)
No, this isn't possible, since all of the *Literal protocols are baked into the compiler with support. Besides, B() is not a literal but a value constructed at runtime; Swift doesn't support custom conversions like C++ does — it uses explicit initializers instead.Betseybetsy
I too long for this features, we could write amazing code with custom ExpressibleBy*Literal protocols.Asyut
H
0

Use custom operators:

postfix operator |

postfix func |(context: Foo) -> Bar {
   Bar(context)
}

let foo = Foo()
let aMyType: Bar = foo|

//Even with generics
postfix func |<C, T>(context: C) -> T

Look for example here

/// Obtain
///
/// let object: T = context|
///

postfix func |<C, T: Obtain>(context: C) -> T {
    Wand.attach(to: context).obtain()
}

https://github.com/El-Machine/Wand

Harshman answered 16/4, 2024 at 6:16 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.