Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 是否可以将类型和协议组合起来,并将其用作枚举的基本类型?_Swift_Enums_Protocols - Fatal编程技术网

Swift 是否可以将类型和协议组合起来,并将其用作枚举的基本类型?

Swift 是否可以将类型和协议组合起来,并将其用作枚举的基本类型?,swift,enums,protocols,Swift,Enums,Protocols,我有一个使用枚举的特殊模式,它总是字符串类型,并且枚举(不是它的原始值)也遵循特定的协议。写得很正常,就像这样 private enum IndicatorA : String, IndicatorProtocol { case X case Y case Z } 我想做的是找出我能做些什么来使字符串隐含,所以我要键入的是 private enum IndicatorA : Indicator { case X case Y case Z }

我有一个使用枚举的特殊模式,它总是字符串类型,并且枚举(不是它的原始值)也遵循特定的协议。写得很正常,就像这样

private enum IndicatorA : String, IndicatorProtocol
{
    case X
    case Y
    case Z
}
我想做的是找出我能做些什么来使字符串隐含,所以我要键入的是

private enum IndicatorA : Indicator
{
    case X
    case Y
    case Z
}
。。。其中,
指示符
指示原始值的类型为
字符串
,枚举本身也遵循
指示符协议

我尝试了这两种方法,想找到一些可以用作原始值类型的方法,但两种方法都无法编译。另外,从技术上讲,这会将协议放在字符串上,而不是枚举上,所以这不是我想要的。(同样,我希望协议位于枚举上,而不是原始值。)


那么,有什么方法可以实现我在Swift 2.x或3.x中试图实现的目标呢?也许是由于某种原因限制了协议?

对此有一些想法:

假设可以使枚举包含一个
指示符
作为其原始值,需要注意的是,这实际上不会使枚举本身符合
指示符协议
,只有其原始值符合。换言之:

enum IndicatorA : String, IndicatorProtocol
这与:

enum IndicatorA : StringThatConformsToIndicatorProtocol
对于第一个示例,您可以如下方式访问协议:

let example:IndicatorA = IndicatorA(rawValue:"Test")
example.someProtocolMethod()
let example:IndicatorA = IndicatorA(rawValue:"Test")
example.rawValue.someProtocolMethod()
对于第二个示例,您必须像这样访问协议:

let example:IndicatorA = IndicatorA(rawValue:"Test")
example.someProtocolMethod()
let example:IndicatorA = IndicatorA(rawValue:"Test")
example.rawValue.someProtocolMethod()
因为在第一个示例中,枚举本身符合协议,但在第二个示例中,枚举的原始值符合协议

综上所述,您可以创建一个符合
StringLiteralConvertible
Equalable
和您自己的
指示符协议的
指示符
结构,从而在某种程度上使第二个示例起作用。例如:

protocol IndicatorProtocol {
    func printHello()
}

struct Indicator: IndicatorProtocol, StringLiteralConvertible, Equatable {
    let string: String
    init(name value: String) {
        self.string = value
    }

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

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

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

    func printHello() {
        print("Hello from \(string)")
    }
}

func ==(left:Indicator, right:Indicator) -> Bool {
    return left.string == right.string

}

enum IndicatorA : Indicator {
    case One = "One", Two = "Two"
}

let test = IndicatorA.One

print(test.rawValue.printHello())   // prints "Hello from One

但这是一个很好的额外工作,以实现一个结果,这不是我认为你希望在第一位

只有
字符串
字符
或任何整数或浮点类型可以是枚举的原始值,因此我不知道这是如何工作的。并且不能对值类型(如
字符串
)进行子分类也许有人证明我错了!此外,我认为原始值类型指示是声明的特权部分。注意,它必须出现在继承列表的开头。是的,我相信它是一个字符串。我只是想让它也遵守这个协议。如果我必须键入
String,Protocol
,这没什么大不了的,但如果可能的话,我很想简化它。@MarqueIV:“我只希望它也遵守这个协议”。你所指的“it”是什么?原始值类型,或枚举本身?枚举。将协议分配给枚举时,静态方法中的枚举将变为“self”,而非静态方法中的个别case语句将变为“self”。例如,在协议中,我定义了一个非静态的
var rawValue:String{get}
,它返回枚举案例的原始值。我需要将该原始值设置为字符串,从而使用字符串定义枚举本身。该协议上有一个扩展,可以使用该字符串值执行某些操作。我在火车上用手机输入,但短版本是否,我没有将指示符作为原始值。我希望字符串是原始值。我还希望枚举符合一个协议,该协议的扩展也期望rawValue是字符串。同样,我想要字符串,协议,但我试图找到是否可以推断字符串。有意义吗?例如,你的第一个例子。我没有让原始值符合任何东西。另外,我实际上使用了默认的原始值,它们是case语句的字符串表示形式。@MarqueIV啊,我明白了。我不知道有什么方法可以将枚举原始值加上要符合的协议类型别名为单个类型。为了更清楚,我更新了我的问题。你的评论突出了我的不够清楚。希望现在是这样。谢谢你的尝试!:)