如何在Swift

时间:2017-05-16 16:08:18

标签: swift casting swift3

我已经创建了一个自定义Fraction类和Double值的扩展,将它们转换为这样的Fraction。这是我的代码(简化):

  class Fraction {
        var wholeNumber : Int?
        var numerator : Int
        var denominator : Int

        init(wholeNumber:Int?, numerator:Int, denominator:Int) {
            guard denominator > 0 else { fatalError("Denominator can't be equal to zero or negative") }
            if wholeNumber != nil && numerator < 0 { fatalError("Invalid fraction") }
            self.wholeNumber = wholeNumber
            self.numerator = numerator
            self.denominator = denominator
        }
    }

Double扩展名:

extension Double {
    init(_ fraction: Fraction) {
        self = Double((fraction.wholeNumber ?? 0) * fraction.denominator + fraction.numerator) / Double(fraction.denominator)
    }
}

但是我需要添加什么来进行类型转换?使用类型转换我的意思是:

let frac = Fraction(wholeNumber: 2, numerator: 1, denominator: 2)
let double = frac as! Double //Gives warning/error: "Cast from 'Fraction' to unrelated type 'Double' always fails"

你是否可以帮助我反过来投射,所以从Double到Fraction? (我已经有一个Fraction初始化器,它接受一个Double值来转换它)

修改

我知道我可以使用初始化程序Double(frac),但这不是我想要实现的目标。我想在Float和CGFloat之间进行类型转换。我提供了Double扩展只是为了展示我如何制作一个分数的Double。 正如@JuicyFruit所说,只有当一个类型是另一个类型的子类时,才可以执行此转换,那么如何使Fraction成为Double的子类,以便我可以将一个Fraction转换为Double? < / p>

2 个答案:

答案 0 :(得分:2)

你应该let double = Double(frac)并查看Apple Documentation关于类型转换的内容:

  

类型转换是一种检查实例类型或处理的方法   该实例作为某个地方的不同超类或子类   在其自己的类层次结构中。

Fraction不是Double的子类,Double无法进行子类化,因为它是struct。您无法将Float投射到Doubleexample

答案 1 :(得分:2)

就几乎所有类型系统而言(包括Swift),FractionDouble都是完全不相关的类型。某些语言(如C#或C ++)具有内置的功能,可以定义此类不相关类型之间的转换行为。可以说,这会引入大量烟雾和镜子,并且可能使代码很难遵循。斯威夫特赞成更冗长的方法:

let double = Double(fraction)