You could also create a “Range” protocol with “lowerBound” and “upperBound” properties. Conform all the range types to it, and make your function take generic over the protocol.
Nevin On Wed, Oct 12, 2016 at 7:21 PM, Hooman Mehr via swift-users < swift-users@swift.org> wrote: > I recommend having explicit precondition and reducing repetition like this: > > import Foundation > > func random(from range: CountableRange<Int>) -> Int { > > precondition(range.count > 0, > "The range can't be empty.") > > return random(from: CountableClosedRange(range)) > } > > func random(from range: CountableClosedRange<Int>) -> Int { > > let lowerBound = range.lowerBound > let upperBound = range.upperBound > > precondition(upperBound - lowerBound < Int(UInt32.max), > "The range \(range) is too wide. It shouldn't be wider > than \(UInt32.max).") > > return lowerBound + Int(arc4random_uniform(UInt32(upperBound - > lowerBound + 1))) > } > > let r1 = random(from: 4 ..< 8) > let r2 = random(from: 6 ... 8) > > Once we have the new improved Integer protocols > <https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md> > in > place, you will be able to make it generic to support all integer types. > (It is possible now, but too messy to be worth doing.) > > > On Oct 12, 2016, at 1:23 PM, Adriano Ferreira via swift-users < > swift-users@swift.org> wrote: > > Hi there! > > Ole Begeman offers here <https://oleb.net/blog/2016/09/swift-3-ranges/> (take > a look at the bottom of the page) an interesting consideration about > converting between half-open and closed ranges. > > As of now, it seems the way to go is by overloading… > > > import Foundation > > func random(from range: Range<Int>) -> Int { > let lowerBound = range.lowerBound > let upperBound = range.upperBound > > return lowerBound + Int(arc4random_uniform(UInt32(upperBound - > lowerBound))) > } > > func random(from range: ClosedRange<Int>) -> Int { > let lowerBound = range.lowerBound > let upperBound = range.upperBound > > return lowerBound + Int(arc4random_uniform(UInt32(upperBound - > lowerBound + 1))) > } > > let r1 = random(from: 4 ..< 8) > let r2 = random(from: 6 ... 8) > > > Cheers, > > — A > > On Oct 12, 2016, at 6:21 AM, Jean-Denis Muys via swift-users < > swift-users@swift.org> wrote: > > Hi, > > I defined this: > > func random(from r: Range<Int>) -> Int { > let from = r.lowerBound > let to = r.upperBound > > let rnd = arc4random_uniform(UInt32(to-from)) > return from + Int(rnd) > } > > so that I can do: > > let testRandomValue = random(from: 4..<8) > > But this will not let me do: > > let otherTestRandomValue = random(from: 4...10) > > The error message is a bit cryptic: > > “No ‘…’ candidate produce the expected contextual result type ‘Range<Int>’” > > What is happening is that 4…10 is not a Range, but a ClosedRange. > > Of course I can overload my function above to add a version that takes a > ClosedRange. > > But this is not very DRY. > > What would be a more idiomatic way? > > Thanks, > > Jean-Denis > > _______________________________________________ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users > > > _______________________________________________ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users > > > > _______________________________________________ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users > >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users