我有一些代碼,濫用Double
在幾乎相同的方式爲String
被濫用爲goto語句爲無類型的類型。以這種方式使用Double
會導致很多細微的和/或隱藏的問題,通常由於有害的運行時錯誤而出現。這兩種方法是什麼樣子現在:使用squant庫,如何爲一種方法指定特定的度量單位?
object Geospatial {
def calculateDistance(
coordinate1Longitude: Double,
coordinate1Latitude: Double,
coordinate2Longitude: Double,
coordinate2Latitude: Double
): (Double, Double, Double) = {
//code encapsulated here only works with meters and radians
//returns (distance in meters, initial bearing in zero-based radians, final bearing in zero-based radians)
???
}
def calculateCoordinate(
coordinate1Longitude: Double,
coordinate1Latitude: Double,
angle: Double,
distance: Double
): (Double, Double) = {
//code encapsulated here only works with meters and radians
//returns angle in radians for longitude and latitude
???
}
}
你可以想像,如果客戶端調用這些方法之一,並沒有正確地轉換爲米,弧度和/或也忘的方法是以米和弧度返回值,客戶端將得到不正確的結果。
所以,我想大大提高上述方法的類型安全性;即,如果/當客戶端試圖調用這些方法中的任何一種時,客戶端會收到編譯時錯誤,而這些方法所傳遞的類型並不完全匹配這些方法需要的類型。本着這種精神,我已經重寫方法(和它們的上下文)更類型化(但仍不足以):
object Geospatial {
type AngleRadiansCentered = Double
//angle's range is restricted to [-Math.PI until Math.PI]
type AngleRadiansPositive = Double
//angle's range is restricted to [0.0d until (Math.PI * 2.0d)]
type LongitudeRadians = AngleRadiansCentered
type LatitudeRadians = AngleRadiansCentered //angle's range must be _further_ restricted to -(Math.PI/2.0d) until (Math.PI/2.0d)
def calculateDistance(
coordinate1: (Longitude, Latitude),
coordinate2: (Longitude, Latitude)
): (Meters, AngleRadiansPositive, AngleRadiansPositive) = {
//Legacy code encapsulated here only works with meters and radians
//returns (distance, initial bearing, final bearing)
???
}
def calculateCoordinate(
coordinate1: (Longitude, Latitude),
bearing: AngleRadiansPositive,
distance: Meters
): (Longitude, Latitude) = {
//Legacy code encapsulated here only works with meters and radians
???
}
}
正如我已經工作這個問題,我最近發現了squants庫。我想我想用squants來重寫上面的代碼。然而,在花了一個小時左右的時間閱讀稀少的文檔(至少在我的上下文中是相關的例子)之後,我無法在如何將它應用於這個問題上做出任何合理的飛躍。例如,如何將其指定爲方法參數,它只接受Meters
(而不是更通用的Length
)。 IOW,我正在尋找類型安全性,而不是類型之間的轉換(儘管這是我將在這些方法之外進行的)。
我找不到任何squants示例代碼snippits,從中我可以得到我所需要的。我並沒有要求完整的解決方案。我只需要指出正確的方向。首先,我需要知道squants是否是真正適合使用的API。然後,如果是這樣,我需要足夠的幫助將我推向正確的大方向,這樣我才能找出剩餘的解決方案空間。
我確實打算至少使用案例類來替換所有Double
的實例。然而,在我這樣做之前,我想知道我是否可以通過squants圖書館來做到這一點。
任何有關這方面的指導將不勝感激。
爲什麼不接受任何'Length',然後使用['toMeters'方法(https://github.com/garyKeorkunian將其轉換爲'Meter' /squants/blob/a4e3cdc6a39d5b4a4fa7f0cdede065fd32d762ab/shared/src/main/scala/squants/space/Length.scala#L71)? –
我曾考慮過這個問題,但無法看到如何保證客戶端知道該功能需要明確預計米和弧度。然而,現在我已經看到了阿爾瓦羅的回答,我想我有點明白你的建議可能如何工作。 – chaotic3quilibrium