1

I'm currently upgrading a forked Framework to Swift 3.

Working Swift 2 Code:

public extension CGFloat {

    var roundToNearestHalf: CGFloat {
        return round(self * 2)/2 
    }
}

In Swift 3, the return throws the compiler error : Cannot use mutating member on immutable value: 'self' is immutable.

I was able to find tons of documentations why a method of a Struct need to to mutable. But so far I'm not able to find a solution for a variable.

If I enter the keyword mutating, the compiler throws the error: Expected declaration

public extension CGFloat {

    var roundToNearestHalf: CGFloat mutating {
        return round(self * 2)/2
    }
}

enter image description here

My research on this issue is, that the code seems to be misplaced - so it needs to be within a function.

public extension CGFloat {

    mutating func roundToNearestHalf() -> CGFloat {
        var roundToNearestHalf: CGFloat {
            return round(self * 2)/2
        }
    }
}

Now the compiler complains about the `*``

enter image description here

Research on that issue brought me to this Thread, that suggests to use the round function the way I'm trying too.

Since this code obviously worked till Swift 3, I'd like to know why it does not anymore. Why does a var has to be declared as mutable now? And how do I need to declare the var roundToNearestHalf now? Help is very appreciated.

Community
  • 1
  • 1
David Seek
  • 16,783
  • 19
  • 105
  • 136
  • You don't need to (nor can you) mark anything as `mutating` – you just need to say `return Darwin.round(self * 2)/2` or `(self * 2).rounded()/2` – Hamish Oct 15 '16 at 10:01
  • `(self * 2).rounded()/2` did it, thank you very much for your efford – David Seek Oct 15 '16 at 10:04
  • @Hamish feel free to answer – David Seek Oct 15 '16 at 10:05
  • I don't think that I've said anything that I haven't said in [my answer to the linked Q&A](http://stackoverflow.com/a/38767820/2976878). If you think that it solves your problem, then feel free to accept the dupe mark :) – Hamish Oct 15 '16 at 10:05
  • I can't accept it, but I have upvoted the Q&A answer – David Seek Oct 15 '16 at 10:06
  • Chat was a miss-click, but I have literally no option to accept the flag – David Seek Oct 15 '16 at 10:07
  • Huh, weird. I was always under the impression that the OP gets prompted whether they want to accept a suggested dupe mark. Never mind, we can just wait for someone to come along with a dupe hammer. – Hamish Oct 15 '16 at 10:09
  • all i am able to accept are edit. whatever you got the well earned upvote. i also have been researching for about 30 minutes, but i haven't come up with the idea to google for `round` itself... was googleing for mutable vars of strucs and whatever... guess this Swift3 stuff will cost me some more sleepless nights...^^ – David Seek Oct 15 '16 at 10:16
  • `passion for Swift, and a tolerance for Objective-C.` tolerance for Objective-C lol xD – David Seek Oct 15 '16 at 10:17

1 Answers1

2

Immutable things now usually have past participle names.

joined(), reversed(), rounded() methods that support fluent chaining

where before there were lots of free functions in present tense that took an argument grammatically in accusative case

like join(x), round(x)... they grammatically look very similar, which made round look like it would change x even though it didn't. Now it does :)

Now everything is way more streamlined, that's the big API change everybody is talking about :)

yeoman
  • 1,671
  • 12
  • 15
  • thank you very much for your answer and explanation – David Seek Oct 15 '16 at 10:05
  • You're very welcome :) – yeoman Oct 15 '16 at 10:06
  • For collections that I write, I use the names plus, with, and without for add, put, remove btw. These are not past participles but still very clear about creating a new thing in stead of modifying the existing instance en lieu. – yeoman Feb 24 '18 at 07:24