Ios 如何使用方法参数中的原始类型坚持协议方法? 协议测量{ 变异函数转换(#toUnit:String) } 枚举质量单位:字符串{ 案例毫克=“毫克” } 枚举卷单位:字符串{ 箱毫升=“毫升” } 结构质量:测量{ 变异函数转换(#toUnit:MassUnit) //生成错误:不符合“测量” } 结构体积:测量{ 变异函数转换(#toUnit:VolumeUnit) //生成错误:不符合“测量” } func+(左:T,右:T)->测量{ 让newRightValue=right.convert(toUnit:left.unit) 返回T(数量:left.quantity+newRightValue.quantity,单位:left.unit) }

Ios 如何使用方法参数中的原始类型坚持协议方法? 协议测量{ 变异函数转换(#toUnit:String) } 枚举质量单位:字符串{ 案例毫克=“毫克” } 枚举卷单位:字符串{ 箱毫升=“毫升” } 结构质量:测量{ 变异函数转换(#toUnit:MassUnit) //生成错误:不符合“测量” } 结构体积:测量{ 变异函数转换(#toUnit:VolumeUnit) //生成错误:不符合“测量” } func+(左:T,右:T)->测量{ 让newRightValue=right.convert(toUnit:left.unit) 返回T(数量:left.quantity+newRightValue.quantity,单位:left.unit) },ios,swift,protocols,Ios,Swift,Protocols,如何使质量正确地符合测量值?需要对测量协议进行哪些更改才能使其与字符串类型的枚举一起工作 更新了问题,提供了有关convert方法签名为什么应该说明给定参数的更多信息。代码是我正在构建的一个开源单元框架的一部分,这个框架名为,在处理单元转换时,我建议不要尝试使用字符串s来表示单元,当转换上面设置的方式时。这将使您的代码在每次进行转换时检查字符串时变得复杂。另外,如果要使用质量单位/体积单位而不是字符串,该怎么办 我建议使用类似于下面概述的设置。它引用了我以前的回答- (注意-我排除了与体积有关的

如何使
质量
正确地符合
测量值
?需要对
测量
协议进行哪些更改才能使其与
字符串
类型的枚举一起工作


更新了问题,提供了有关convert方法签名为什么应该说明给定参数的更多信息。代码是我正在构建的一个开源单元框架的一部分,这个框架名为

,在处理单元转换时,我建议不要尝试使用
字符串
s来表示单元,当转换上面设置的方式时。这将使您的代码在每次进行转换时检查
字符串时变得复杂。另外,如果要使用
质量单位
/
体积单位
而不是
字符串
,该怎么办

我建议使用类似于下面概述的设置。它引用了我以前的回答-

(注意-我排除了与体积有关的任何内容,因为它基本上与mass的实现相同)

我会这样做的单位:

protocol Measurement {
     mutating func convert(#toUnit: String)
}

enum MassUnit : String {
    case Milligram = "mg"
}

enum VolumeUnit : String {
     case Milliliter = "ml"
}

struct Mass : Measurement {
     mutating func convert(#toUnit: MassUnit)
     // Build error: Does not adhere to 'Measurement'
}

struct Volume : Measurement {
     mutating func convert(#toUnit: VolumeUnit)
     // Build error: Does not adhere to 'Measurement'
}

func +<T: Measurement> (left:T, right:T) -> Measurement {
    let newRightValue  = right.convert(toUnit: left.unit)
    return T(quantity: left.quantity + newRightValue.quantity , unit: left.unit)
}
protocol UnitProtocol {
    var magnitude: Int { get }

    init?(rawValue: String)
}

// Taken from my previous answer.
enum MassUnit: String, UnitProtocol, Printable {
    case Milligram = "mg"
    case Gram      = "g"

    var magnitude: Int {
        let mag: Int

        switch self {
            case .Milligram: mag = -3
            case .Gram     : mag =  0
        }

        return mag
    }

    var description: String {
        return rawValue
    }
}

// Not making this a method requirement of `UnitProtocol` means you've only got to 
// write the code once, here, instead of in every enum that conforms to `UnitProtocol`.
func ordersOfMagnitudeFrom<T: UnitProtocol>(unit1: T, to unit2: T) -> Int {
    return unit1.magnitude - unit2.magnitude
}
现在开始转换函数!使用全局函数意味着您不需要为符合
UnitConstruct
的每种类型重写代码

protocol UnitConstruct {
    typealias UnitType: UnitProtocol
    var amount: Double   { get }
    var unit  : UnitType { get }

    init(amount: Double, unit: UnitType)
}

struct Mass : UnitConstruct {
    let amount: Double
    let unit  : MassUnit
}

在处理单位转换时,我建议不要尝试使用
String
s来表示单位,而要按照上面的设置进行转换。这将使您的代码在每次进行转换时检查
字符串时变得复杂。另外,如果要使用
质量单位
/
体积单位
而不是
字符串
,该怎么办

我建议使用类似于下面概述的设置。它引用了我以前的回答-

(注意-我排除了与体积有关的任何内容,因为它基本上与mass的实现相同)

我会这样做的单位:

protocol Measurement {
     mutating func convert(#toUnit: String)
}

enum MassUnit : String {
    case Milligram = "mg"
}

enum VolumeUnit : String {
     case Milliliter = "ml"
}

struct Mass : Measurement {
     mutating func convert(#toUnit: MassUnit)
     // Build error: Does not adhere to 'Measurement'
}

struct Volume : Measurement {
     mutating func convert(#toUnit: VolumeUnit)
     // Build error: Does not adhere to 'Measurement'
}

func +<T: Measurement> (left:T, right:T) -> Measurement {
    let newRightValue  = right.convert(toUnit: left.unit)
    return T(quantity: left.quantity + newRightValue.quantity , unit: left.unit)
}
protocol UnitProtocol {
    var magnitude: Int { get }

    init?(rawValue: String)
}

// Taken from my previous answer.
enum MassUnit: String, UnitProtocol, Printable {
    case Milligram = "mg"
    case Gram      = "g"

    var magnitude: Int {
        let mag: Int

        switch self {
            case .Milligram: mag = -3
            case .Gram     : mag =  0
        }

        return mag
    }

    var description: String {
        return rawValue
    }
}

// Not making this a method requirement of `UnitProtocol` means you've only got to 
// write the code once, here, instead of in every enum that conforms to `UnitProtocol`.
func ordersOfMagnitudeFrom<T: UnitProtocol>(unit1: T, to unit2: T) -> Int {
    return unit1.magnitude - unit2.magnitude
}
现在开始转换函数!使用全局函数意味着您不需要为符合
UnitConstruct
的每种类型重写代码

protocol UnitConstruct {
    typealias UnitType: UnitProtocol
    var amount: Double   { get }
    var unit  : UnitType { get }

    init(amount: Double, unit: UnitType)
}

struct Mass : UnitConstruct {
    let amount: Double
    let unit  : MassUnit
}

您可能会将
enum MassUnit:String
与继承混淆

与表示
ChildClass
继承自
ParentClass
class-ChildClass:ParentClass
相反,
enum-MassUnit:String
的含义稍有不同,说明枚举的原始类型是
String
,而不是枚举继承字符串类型

因此,
MassUnit
不是字符串类型。您的
MassUnit
rawValue
s属于String类型,但要访问该类型,您需要调用枚举的
rawValue
属性,以获得该
字符串的等效值


因此,
mutating func convert(#toUnit:String)
mutating func convert(#toUnit:massttype)
不兼容,因为
massttype
本身不是
字符串。只有它的
rawValue
是。

您可能会将
enum MassUnit:String
与继承混淆

与表示
ChildClass
继承自
ParentClass
class-ChildClass:ParentClass
相反,
enum-MassUnit:String
的含义稍有不同,说明枚举的原始类型是
String
,而不是枚举继承字符串类型

因此,
MassUnit
不是字符串类型。您的
MassUnit
rawValue
s属于String类型,但要访问该类型,您需要调用枚举的
rawValue
属性,以获得该
字符串的等效值


因此,
mutating func convert(#toUnit:String)
mutating func convert(#toUnit:massttype)
不兼容,因为
massttype
本身不是
字符串。只有它的原始值是。

啊,谢谢,我试试。我可以更新问题,原因是我需要方法签名中的MassUnit,现在也更新了,所以没有办法确保协议可以与Enum一起正常运行?只是说String可能会让人困惑和不清晰。我再次更新了我的答案:)我意识到你想用
String
s转换。
UnitProtocol
有点变化,有一个新的
convert
功能。最后举例说明。很高兴我能帮忙,祝你的项目好运!现在差不多了。这个solotuion唯一没有提供的是在对象上使用convert方法的能力,这是首选的。例如
让千克=质量(数量:1,单位:.Kilo)让克=千克。转换(土尼:克)
我个人更喜欢使用全局函数。但是,如果您想改用实例方法,您可以在方法
func convertMass(to:MassUnit)->Mass{return convert(self,toUnits:to)}
中添加一个啊,谢谢,我试试看。我可以更新问题,原因是我需要方法签名中的MassUnit,现在也更新了,所以没有办法确保协议可以与Enum一起正常运行?仅仅说字符串可能会混淆和不清楚