Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Gene Bogdanovich
Gene Bogdanovich
14,618 Points

How can I make this code work?

How can I make this code work so that the slide function directly changes the potential properties of two objects? I tried inout parameters, but there was a lot of type confusion. I would really appreciate any sort of help.

import CoreGraphics

protocol Moveable {
    mutating func move(to point: CGPoint)
}

class Car: Moveable {
    func move(to point: CGPoint) {} // changes some properties of the object e.g. x and y values
}

struct Ball: Moveable {
    mutating func move(to point: CGPoint) {} // changes some properties of the object e.g. x and y values
}

var car = Car()
var ball = Ball()

func slide(_ thingToSlide: Moveable) {
    let positionToSlideTo = CGPoint(x: 4, y: 6)
    thingToSlide.move(to: positionToSlideTo) // error because the function parameter is immutable
}

slide(car)
slide(ball)

1 Answer

Jhoan Arango
Jhoan Arango
14,575 Points

Hello,

An easy solution is to pass that parameter into a new variable:

func slide(_ thingToSlide: Moveable) {
    let positionToSlideTo = CGPoint(x: 4, y: 6)

    var thingsToSlide = thingToSlide
    thingsToSlide.move(to: positionToSlideTo) // error because the function parameter is immutable
}

if this is not what you are looking for let me know, we can go with more advance solution.

Good luck

Gene Bogdanovich
Gene Bogdanovich
14,618 Points

This works with Reference Types but with Value Types it doesn't. Perhaps more advanced solution that you mentioned will solve this problem.

protocol Moveable {
    mutating func move(to point: CGPoint)
}

class Car: Moveable {
    var position: CGPoint
    func move(to point: CGPoint) {
        position.x = point.x
        position.y = point.y
    }

    init(position: CGPoint) {
        self.position = position
    }
}

struct Ball: Moveable {
    var position: CGPoint
    mutating func move(to point: CGPoint) {
        position.x = point.x
        position.y = point.y
    }
}

var car = Car(position: CGPoint(x: 2, y: 2))

var ball = Ball(position: CGPoint(x: 3, y: 4))

car.position // {x 2 y 2}
ball.position // {x 3 y 4}

func slide(_ thingToSlide: Moveable) {
    let positionToSlideTo = CGPoint(x: 4, y: 6)
    var a = thingToSlide
    a.move(to: positionToSlideTo)
}

slide(car)
car.position // {x 4 y 6}
slide(ball)
ball.position // {x 3 y 4}
Jhoan Arango
Jhoan Arango
14,575 Points

Correct,

I thought you wanted to fix the function's error.

In your case you may want to try something like this.

var car = Car(position: CGPoint(x: 2, y: 2))
var ball = Ball(position: CGPoint(x: 3, y: 4))

car.position // {x 2 y 2}
ball.position // {x 3 y 4}

func slide(_ thingToSlide: Moveable, to position: CGPoint) -> Moveable {  
    var a = thingToSlide // Making the object mutable or a new copy
    a.move(to: position) // Changing the objects position

    return a // Returning the new object
}

car = slide(car, to: CGPoint(x: 7, y: 7) ) as! Car // Assigning the new car and casting it to its correct Object
car.position // {x 7 y 7}

ball = slide(ball, to:  CGPoint(x: 2, y: 2)) as! Ball // Assigning the new ball and casting it to its correct Object
ball.position // {x 2 y 2}

Hope this helps