- Hands-On Design Patterns with Swift
- Florent Vilmart Giordano Scalzo Sergio De Simone
- 445字
- 2021-07-02 14:44:58
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)
}
}
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
- Building Computer Vision Projects with OpenCV 4 and C++
- Python絕技:運用Python成為頂級數據工程師
- 數據庫基礎與應用:Access 2010
- Test-Driven Development with Mockito
- Python金融大數據分析(第2版)
- 網站數據庫技術
- 基于OPAC日志的高校圖書館用戶信息需求與檢索行為研究
- 大數據架構商業之路:從業務需求到技術方案
- HikariCP連接池實戰
- Google Cloud Platform for Developers
- 利用Python進行數據分析(原書第2版)
- 數據挖掘與機器學習-WEKA應用技術與實踐(第二版)
- 一本書讀懂大數據
- 數字化轉型方法論:落地路徑與數據中臺
- 代碼的未來