Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

220
Visualizações
Swift, struct. How to simplify struct multiple property .dot accessors?

I have some structs that represent locations on the Earth that represent a simple lat/lon location (Point2D), lat/lon/height location (Point3D), and a named location such as an airport name/lat/lon/height location (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
}

These structs are used hierarchically which works fine, but it does cause some long .dot access when getting data out of an airport instance. For example, to get the airport's latitude value is airport.point3D.point2D.lat which is not ideal.

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

I have refactored the airport struct to 'flatten' the property .dot access, but I feel that there may be a better way to achieve this.

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)
  }
}

Accessing the airport's data is now much simpler...

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

... but is there a better way to do this?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Assuming you mean altitude by height, you can simply make use of CLLocation, and optionally extend it with a convenience initializer to make life a little easier.

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
over 4 years ago · Santiago Trujillo Relatório

0

I would suggest:

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 }
}

Above, following best practices, I have favored immutability. But if you really need mutability:

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 }
    }
}

Unrelated, but I would probably move these computed properties into a Place protocol:

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
}

That way you can define places that are not airports, too, and not have to repeat these computed properties.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda