Сначала вам нужен протокол CustomDoubleConvertible
. Это зеркало CustomStringConvertible
. Вы распространяете все типы, которые хотите конвертировать в Double
. Аналогично description
, который возвращает представление типа String
.
protocol CustomDoubleConvertible {
var doubleValue : Double { get }
}
extension Int : CustomDoubleConvertible {
var doubleValue : Double { return Double(self) }
}
extension Int16 : CustomDoubleConvertible {
var doubleValue : Double { return Double(self) }
}
Если сделать функцию расширения для Range
сама вы можете использовать это общий характер, и это typealiases
.
extension Range where Element.Distance : CustomDoubleConvertible {
Теперь вы можете вычислить смещения индексов примерно так:
let startOffset = Int(portion * self.count.doubleValue)
let endOffset = Int(portion * self.count.doubleValue)
Если вы еще больше ограничивают Range
так, что это Element
должно быть BidirectionalIndexType
вы можете использовать successor
и predecessor
.
extension Range where Element.Distance : CustomDoubleConvertible, Element : BidirectionalIndexType {
Это позволяет получить полную функцию перебора смещений и вызова successor
и predecessor
.
extension Range where Element.Distance : CustomDoubleConvertible, Element : BidirectionalIndexType {
func truncateTailsOfRange(portion: Double) -> Range<Element> {
let startOffset = Int(portion * self.count.doubleValue)
let endOffset = Int(portion * self.count.doubleValue)
var start = self.startIndex
var end = self.endIndex
for _ in 0..<startOffset { start = start.successor() }
for _ in 0..<endOffset { end = end.predecessor() }
return Range(start: start, end: end)
}
}
Некоторые тесты:
let rangeA = 1...4 // 1..<5
let rangeB = "a"..."g"
rangeA.truncateTailsOfRange(0.3) // 2..<4
rangeB.truncateTailsOfRange(0.3) // has no member ....
let w : Int16 = 3
let z : Int16 = 9
let rangeC = w...z // 3..<10
rangeC.truncateTailsOfRange(0.4) // 5..<8
Вам нужен диапазон для всех целочисленных типов ? Было бы намного проще создать метод для каждого из них, который вам нужен. –
Мне нужен только Int, но мотивация была просто в том, что нет оснований ограничивать это ints. –
Вы пытаетесь вызвать конструктор на T, но T не является фактическим классом/struct/enum, а скорее просто «типом» «. – davecom