0

Im having some very frustrating issues with this function:

func degToRad(deg:Int) -> Float {
    return deg*(M_PI/180.0)
}

At the return line I get an error message: 'Int' is not convertible to 'UInt8'

This is really driving me nuts. This would work in Obj-C. Im really starting to question Swift as a language...


UPDATE

I updated my function to this:

func degToRad(deg:Double) -> CGFloat {
    return CGFloat(deg*(M_PI/180.0))
}

But when I try to use it like this:

CGAffineTransformMakeRotation(CFunctions.degToRad(90))

I get the same error except Double -> CGFloat not convertible

Shruti Thombre
  • 989
  • 4
  • 11
  • 27
Arbitur
  • 38,684
  • 22
  • 91
  • 128

3 Answers3

10

There is no implicit type conversion in Swift for safety reasons. You must convert deg to a Float. Literals don't have an implicit type and can act as number of different types, but by initiating the division first, the type is chosen before it can be decided by the type of deg. Therefore, you must convert the result of M_PI/180.0 as well:

func degToRad(deg: Int) -> Float {
    return Float(deg) * Float(M_PI / 180.0)
}

And to potentially entice you with the language a bit more. Here is a handy enum for AngularMeasure:

enum AngularMeasure {
    case Degrees(CGFloat)
    case Radians(CGFloat)

    var degrees: CGFloat {
        switch (self) {
            case let .Degrees(value):
                return value
            case let .Radians(value):
                return value * CGFloat(180.0 / M_PI)
        }
    }

    var radians: CGFloat {
        switch (self) {
            case let .Degrees(value):
                return value * CGFloat(M_PI / 180.0)
            case let .Radians(value):
                return value
        }
    }
}

var measure : AngularMeasure = .Degrees(180)
println(measure.radians) // 3.14159274101257

Edit:

With your update, you are trying to call an instance method as a class method. You need to define your method as a class method:

class func degToRad(deg:Double) -> CGFloat {
    return CGFloat(deg*(M_PI/180.0))
}

Again, this is a terrible compiler error.

drewag
  • 93,393
  • 28
  • 139
  • 128
4

The thing to understand is that there is no implicit casting of numeric types to one another. Literals are cast because they have no actual type at the outset, but variables are not.

The only "natural" types are Int and Double, and Float is neither of those. Thus, to return a Float you need to cast the whole result to a Float:

func degToRad(deg:Int) -> Float {
    return Float(deg*(M_PI/180.0))
}

But even this will not be enough, because deg comes in as an Int, while M_PI and 180.0 are Double, so it must be cast too:

func degToRad(deg:Int) -> Float {
    return Float(Double(deg)*(M_PI/180.0))
}
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 5
    Having said all that, Swift's compiler messages in these situations are intolerably misleading. I wish everyone would file a bug every time the compiler makes you look in the wrong place. – matt Jul 20 '14 at 15:58
  • Also please file an enhancement request if you want more implicit numeric casting. See my question here: http://stackoverflow.com/questions/24108827/swift-numerics-and-cgfloat-cgpoint-cgrect-etc where I point out that we are going to be banging into this issue a _lot_ because we must constantly interface with CGFloat. – matt Jul 20 '14 at 16:01
  • I see I changed deg to a Double and return type to CGFloat but now when I try to use it in a CGAffineTransformMakeRotation(degToRad(90.0)) I get another error saying "Double -> CGFloat is not convertible to CGFloat" Even when the return type is CGFloat – Arbitur Jul 20 '14 at 16:09
  • 1
    @Arbitur Stop trying to mix and match types. If you want to return CGFloat, return CGFloat, not Double. CGFloats are not always Doubles. – Mick MacCallum Jul 20 '14 at 16:14
  • @0x7fffffff I am not returning a Double, Ill update my answer. – Arbitur Jul 20 '14 at 16:15
1

The error message looks like a current deficiency in the compiler but the mistake is not explicitly casting deg to Float. There is no implicit type conversion in Swift (teleologically because the bugs it sometimes produces are not considered worth the reduction in syntax).

Tommy
  • 99,986
  • 12
  • 185
  • 204