官术网_书友最值得收藏!

Struct

Now, let's try to port our Point class into a struct. Consider the following:

struct Point {
var x: Double
var y: Double
}

We have defined a simple struct; as you should notice, there's no need to add a constructor, as the compiler will synthesize it for us:

let point = Point(x: 0.0, y: 0.0)
translate(point: point, dx: 1.0, dy: 1.0)

If we keep the original implementation, our program won't compile. Point is a value type now, and it's forbidden to mutate a value inside of a function! We need to add the inout keyword to indicate that this function will mutate the contents of the value that is passed. When the function returns, the value will be assigned back to the original variable.

With those changes complete, we also need to change our call to indicate that our point variable can be modified by our translate function with the & (ampersand) character. We also need to mark our point as var; otherwise, the inout function cannot modify its contents:

func translate(point: inout Point, dx : Double, dy : Double) {
point.x += dx
point.y += dy
}

var point = Point(x: 0.0, y: 0.0)
translate(&point, dx: 1.0, dy: 1.0)
point.x == 1.0 // true
point.y == 1.0 // true

We've successfully ported this function, but we can do better.

With structs, you will often see that this pattern is cumbersome. We may want the translate function to return a mutated copy of the value we passed in, as follows:

func translate(point: Point, dx : Double, dy : Double) -> Point {
var point = point
translate(point: &point, dx : dx, dy : dy)
return point
}

We'll be able to use the previously defined function with the following code:

let point = Point(x: 0.0, y: 0.0)
let translatedPoint = translate(point, dx: 1.0, dy: 1.0)
point.x == 0.0
point.y == 0.0
translatedPoint.x == 1.0
translatedPoint.y == 1.0

With this new implementation, we're not mutating the value anymore, but the translate function is always returning a new Point value. This has many benefits, including the ability to chain such calls together. Let's add a method to our Point struct:

extension Point {
func translating(dx: Double, dy: Double) -> Point {
return translate(point: self, dx: dx, dy: dy)
}
}
You don't need to declare this new method in your struct, but you can declare it anywhere in your program. 

Using our newly crafted extension, we can easily create new Point values and translate them:

let point = Point(x: 0.0, y: 0.0)
.translating(dx : 5.0, dy : 2.0)
.translating(dx : 2.0, dy : 3.0)
point.x == 7.0
point.y == 5.0
主站蜘蛛池模板: 绩溪县| 美姑县| 高平市| 瓮安县| 定结县| 泾阳县| 江都市| 黎平县| 搜索| 太仆寺旗| 灵璧县| 蒙自县| 神木县| 丰城市| 德钦县| 巨野县| 海南省| 吕梁市| 福泉市| 宜川县| 高密市| 锦屏县| 师宗县| 卢氏县| 邢台县| 望都县| 邢台县| 沾益县| 栖霞市| 太原市| 定州市| 水城县| 邹城市| 富裕县| 裕民县| 当涂县| 沙湾县| 加查县| 宜宾县| 土默特左旗| 吕梁市|