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 <mailto: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 <mailto: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 <mailto:swift-users@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-users >> <https://lists.swift.org/mailman/listinfo/swift-users> > > _______________________________________________ > swift-users mailing list > swift-users@swift.org <mailto: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