简体   繁体   中英

Why can't I use min() on a tuple of doubles in Swift?

var coordinatesDouble = (Double(latitudeTextField.text!), Double(longitudeTextField.text!))

var boundingBoxLat: (Double, Double)
var boundingBoxLon: (Double, Double)

boundingBoxLat = (coordinatesDouble.0! - Constants.Flickr.SearchBBoxHalfHeight, coordinatesDouble.1! + Constants.Flickr.SearchBBoxHalfHeight)
boundingBoxLon = (coordinatesDouble.1! - Constants.Flickr.SearchBBoxHalfWidth, coordinatesDouble.1! + Constants.Flickr.SearchBBoxHalfWidth)

if min(boundingBoxLat) < -90.0 {

I am trying to use min() in an if statement, but am getting the error:

"Cannot invoke 'min' with an argument list of type (Double, Double)"

I thought this was specifically what this function was for. Am I missing something?

The equation for each double is one double being subtracted or added to another, resulting in a double. The if statement should then be determining if the lowest value in the tuple is lower than -90.0.

Am I missing something?

YES.

Please check this: SE-0029 Remove implicit tuple splat behavior from function applications

In the versions of Swift which include this SE-0029, Swift does not accept a tuple of two members as an actual parameter for function with two arguments .

(There is another overload for min , but it's irrelevant here.)

As commented by JAL, you need to pass two arguments to call min(_:_:) :

min(boundingBoxLat.0, boundingBoxLat.1)

Some addition.

I wonder if this line is really what you intend:

boundingBoxLat = (coordinatesDouble.0! - Constants.Flickr.SearchBBoxHalfHeight, coordinatesDouble.1! + Constants.Flickr.SearchBBoxHalfHeight)

It should be like this, no? (Please find the small difference in the latter half.):

boundingBoxLat = (coordinatesDouble.0! - Constants.Flickr.SearchBBoxHalfHeight, coordinatesDouble.0! + Constants.Flickr.SearchBBoxHalfHeight)

But it is not important my guess is right or not. Just you should know that this sort of code using tuples too much is less readable.

I recommend you to define your own structure to represent boundingBox :

struct CoordinateBox {
    var minLatitude: Double
    var maxLatitude: Double
    var minLongitude: Double
    var maxLongitude: Double

    init(latitude: Double, longitude: Double, height: Double, width: Double) {
        assert(height > 0.0)
        assert(width > 0.0)
        minLatitude = latitude - height
        maxLatitude = latitude + height
        minLongitude = longitude - width
        maxLongitude = longitude + width
    }
}

let boundingBox = CoordinateBox(latitude: Double(latitudeTextField.text ?? "") ?? 0,
                                longitude: Double(longitudeTextField.text ?? "") ?? 0,
                                height: Constants.Flickr.SearchBBoxHalfHeight,
                                width: Constants.Flickr.SearchBBoxHalfWidth)

if boundingBox.minLatitude < -90.0 {
    //...
}

You would never be confused with .0 s and .1 s.

A tuple can have different data types mixed together. You should use an array if all the datatypes are the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM