简体   繁体   中英

How to define a new “String” type in Apple Swift?

I have reference strings which my app in release builds simply receives from one service and passes to another. For debugging purposes it is necessary to compare two references and print them out to the console.

My app has at least two difference types of reference strings - neither is ever to be assigned to the other.

I'd like to have two unique types in my code, called ArticleReference and ResultReference.

I've started by defining a "generic" protocol from which I can build ArticleReference and ResultReference. Let's just deal with ArticleReference here.

public protocol ReferenceType: Comparable, StringLiteralConvertible {
    var value:String {set get}
    init(_ value:String)
}

public func + <T :ReferenceType> (lhs:T, rhs:T) -> T {
    return T(lhs.value + rhs.value)
}

public func += <T :ReferenceType> (inout lhs:T, rhs:T) -> T {
    lhs.value += rhs.value
}

public func == <T :ReferenceType> (lhs:T, rhs:T) -> Bool {
    return lhs.value == rhs.value
}

public func < <T :ReferenceType> (lhs:T, rhs:T) -> Bool {
    return lhs.value < rhs.value
}

public func > <T :ReferenceType> (lhs:T, rhs:T) -> Bool {
    return lhs.value > rhs.value
}

And here is one of the reference types.

public struct ArticleReference :ReferenceType {
    public var value:String
    public init(_ value:String) {
        self.value = value
    }
}

Xcode 6.4 complains about ArticleReference.

public init(_ value:String) {

Error: Initializer 'init' has different argument from those required by protocol 'StringLiteralConvertible' ('init(stringLiteral:);) and offers to replace '_' with 'stringLiteral

If I accept the change to 'stringLiteral' Xcode then suggests 'stringLiteral' is replaced with '_' ! Infinite error loop.

Am I taking the right approach? And if so where have I gone wrong?

The error message might be misleading. The problem is that protocol ReferenceType inherits from StringLiteralConvertible , but you did not implement the required methods for your struct ArticleReference .

A possible implementation could be

extension ArticleReference: StringLiteralConvertible {

    public init(stringLiteral value: StringLiteralType) {
        self.init(value)
    }

    public init(extendedGraphemeClusterLiteral value: StringLiteralType) {
        self.init(value)
    }

    public init(unicodeScalarLiteral value: StringLiteralType) {
        self.init(value)
    }
}

Adding that makes your code compile without errors.

Multiple init funcs are required in each struct using the ReferenceType protocol.

public struct ArticleReference:ReferenceType {
    public var value:String
    public init(_ value:String) {
        self.value = value
    }

    public init(stringLiteral value:String) {
        self.value = value
    }

    public init(extendedGraphemeClusterLiteral value:String) {
        self.value = value
    }

    public init(unicodeScalarLiteral value:String) {
       self.value = value
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM