有效地包装双倍

时间:2017-04-01 08:35:04

标签: swift swift3 double

我有许多几何函数,只能接受0°到360°范围内的角度。如果角度在该范围之外,则角度无效(即,将365°转换为5°不是一种选择)并且调用函数没有意义。为此我创建了以下类:

struct PositiveAngle {
    public let value: Double

    init?(value: Double) {
        guard 0.0 <= value && value <= 360.0 else {
            return nil
        }
        self.value = value
    }
}

使用方法如下:

let angle = PositiveAngle(value: 30.0)
print(angle.value)

func foo(angle: PositiveAngle) -> PositiveAngle {
    ...
}

这样可行,但感觉“笨重”,因为每当我需要使用它时,我都会从结构中提取角度的值。鉴于我所追求的只是一个范围有限的Double,是否有更有效的方法来实现这一目标?

3 个答案:

答案 0 :(得分:1)

如果您不想在每个功能中访问.value,您必须自己添加帮助功能。

例如,要定义sin

func sin(_ angle: PositiveAngle) -> Double {
    return sin(angle.value * Double.pi / 180)
}

现在,您可以直接使用sin作为参数调用PositiveAngle

您可以为运营商执行相同的操作,例如+-等。

答案 1 :(得分:0)

您可以使用具有静态函数的结构

struct AngleChecker {
    static func validate(_ value : Double) -> Double? {
       return (0.0...360.0).contains(value) ? value : nil
    }
}

let x = AngleChecker.validate(12.0) // --> 12.0
let y = AngleChecker.validate(362.0) // --> nil

答案 2 :(得分:0)

你不想做模数,原因我并不完全清楚,但多年来我做了很多角度数学并且总是使用环绕式。在斯威夫特,

<?php
$address = "Kathmandu, Nepal";
$url = "http://maps.google.com/maps/api/geocode/json?address=".urlencode($address);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    
$responseJson = curl_exec($ch);
curl_close($ch);

$response = json_decode($responseJson);

if ($response->status == 'OK') {
    $latitude = $response->results[0]->geometry->location->lat;
    $longitude = $response->results[0]->geometry->location->lng;

    echo 'Latitude: ' . $latitude;
    echo '<br />';
    echo 'Longitude: ' . $longitude;
} else {
    echo $response->status;
    var_dump($response);
}    
?>

在数学术语中,722º完全相当于2º。