无法为枚举制定协议

Unable to make a protocol for enum

我不太擅长协议,我现在很困惑。我正在尝试为一个 enum 制定一个协议,它有一个 name 属性 (或者如果需要的话可以运行)。

这将允许我获得枚举值的名称,类似于仅符合 String,但首字母大写。例如,我希望发生什么:

enum Furniture: Named {
    case table, chair, lamp
}

Furniture.table.name   // Returns 'Table'
Furniture.chair.name   // Returns 'Chair'
Furniture.lamp.name    // Returns 'Lamp'

这是我目前的情况:

protocol Named {
    var name: String { get }
}

extension Named where Named: String {
    var name: String {
        let str: String = self.rawValue
        return str.prefix(1).uppercased() + str.dropFirst()
    }
}

这给了我错误,当我尝试更正它们时,又弹出了另一个错误。

现在,这显示了以下错误:

Type 'Named' constrained to non-protocol, non-class type 'String'

Value of type 'Self' has no member 'rawValue'

我该如何解决这个问题?

枚举通过 RawRepresentable 协议获得它们的原始值,所以这就是你在限制扩展时应该使用的:

extension Named where Self: RawRepresentable, RawValue == String {
    var name: String {
        let str: String = self.rawValue
        return str.prefix(1).uppercased() + str.dropFirst()
    }
}

您还需要声明您的枚举使用 String 作为其 rawValue 的类型:

enum Furniture: String, Named {
    case table, chair, lamp
}

Furniture enum 设置为原始字符串类型,Swift 编译器会自动添加 RawRepresentable 一致性。

protocol Named {
    var name: String { get }
}

enum Furniture: String, Named {
    case table, chair, lamp
}

extension Named where Self: RawRepresentable, RawValue == String {
    var name: String {
        return rawValue.capitalized
    }
}

用于验证家具枚举的单元测试,

import XCTest

class FurnitureTests: XCTestCase {

    func testEnumDisplayNameFirstLetterCapitlized() {
        XCTAssertEqual(Furniture.table.name, "Table")
        XCTAssertEqual(Furniture.chair.name, "Chair")
        XCTAssertEqual(Furniture.lamp.name, "Lamp")
    }

    func testEnumRawValue() {
        XCTAssertEqual(Furniture.table.rawValue, "table")
        XCTAssertEqual(Furniture.chair.rawValue, "chair")
        XCTAssertEqual(Furniture.lamp.rawValue, "lamp")
    }
}