我有一些代表地球上位置的結構,它們代表簡單的緯度/經度位置 ( Point2D)、緯度/經度/高度位置 ( Point3D) 和命名位置,例如機場名稱/緯度/經度/高度位置 ( Airport)。
struct Point2D {
var lat: Double
var lon: Double
}
struct Point3D {
var point2D: Point2D
var height_m: Double
}
struct Airport {
var name: String
var point3D: Point3D
}
這些結構是分層使用的,效果很好,但是當從機場實體中獲取資料時,它確實會導致一些長的 .dot 訪問。例如,獲取機場的緯度值airport.point3D.point2D.lat是不理想的。
let airportLHR1 = Airport(name: "LHR", point3D: Point3D(point2D: Point2D(lat: 51.5, lon: -0.5), height_m: 25.0))
print("Airport: \(airportLHR1.name). Lat,Lon: \(airportLHR1.point3D.point2D.lat), \(airportLHR1.point3D.point2D.lon)")
// --> Airport: LHR. Lat,Lon: 51.5, -0.5
我已經重構了機場結構以“扁平化”屬性 .dot 訪問,但我覺得可能有更好的方法來實作這一點。
struct Airport2 {
var name: String
private var _point3D: Point3D
var lat: Double { get { _point3D.point2D.lat } set { _point3D.point2D.lat = newValue } }
var lon: Double { get { _point3D.point2D.lon } set { _point3D.point2D.lon = newValue } }
var height_m: Double { get { _point3D.height_m } set { _point3D.height_m = newValue } }
init(name: String, lat: Double, lon: Double, height_m: Double) {
self.name = name
self._point3D = Point3D(point2D: Point2D(lat: lat, lon: lon), height_m: height_m)
}
}
現在訪問機場的資料要簡單得多......
let airportLHR2 = Airport2(name: "LHR", lat: 51.5, lon: -0.5, height_m: 25.0)
print("Airport: \(airportLHR2.name). Lat,Lon: \(airportLHR2.lat), \(airportLHR2.lon)")
// --> Airport: LHR. Lat,Lon: 51.5, -0.5
...但是有沒有更好的方法來做到這一點?
uj5u.com熱心網友回復:
假設您的意思是高度height,您可以簡單地使用CLLocation,并可以選擇使用便利的初始化程式對其進行擴展,以使生活更輕松一些。
extension CLLocation {
convenience init(lat: CLLocationDegrees, lon: CLLocationDegrees, alt: CLLocationDistance) {
self.init(coordinate: CLLocationCoordinate2D(latitude: lat, longitude: lon),
altitude: alt,
horizontalAccuracy: 0,
verticalAccuracy: 0,
timestamp: .now)
}
}
struct Airport {
let name: String
let loc: CLLocation
}
let lax = Airport(name: "LAX", loc: CLLocation(lat: 33.9416, lon: -118.4085, alt: 39.0144))
print(lax.loc.coordinate.longitude) // -118.4085
print(lax.loc.altitude) // 39.0144
uj5u.com熱心網友回復:
我會建議:
struct Coordinate {
let latitude: Double
let longitude: Double
}
struct Location {
let coordinate: Coordinate
let altitude: Double
}
struct Airport {
let name: String
let location: Location
}
extension Airport {
var latitude: Double { location.coordinate.latitude }
var longitude: Double { location.coordinate.longitude }
}
以上,遵循最佳實踐,我贊成不變性。但是如果你真的需要可變性:
struct Coordinate {
var latitude: Double
var longitude: Double
}
struct Location {
var coordinate: Coordinate
var altitude: Double
}
struct Airport {
var name: String
var location: Location
}
extension Airport {
var latitude: Double {
get { location.coordinate.latitude }
set { location.coordinate.latitude = newValue }
}
var longitude: Double {
get { location.coordinate.longitude }
set { location.coordinate.longitude = newValue }
}
}
不相關,但我可能會將這些計算屬性移動到Place協議中:
protocol Place {
var name: String { get }
var location: Location { get }
}
extension Place {
var latitude: Double { location.coordinate.latitude }
var longitude: Double { location.coordinate.longitude }
}
struct Airport: Place {
let name: String
let location: Location
}
這樣,您也可以定義不是機場的地方,而不必重復這些計算的屬性。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/421193.html
標籤:
