(Наверное, название нужно получше...)
Я хотел бы иметь набор средств доступа, которые я мог бы использовать в коде для быстрого выражения длительности времени. Например:
42.seconds
3.14.minutes
0.5.hours
13.days
Этот пост показывает, что вы не можете просто сделать это с помощью простого нового протокола , расширение и принуждение IntegerType
и FloatingPointType
принять это. Поэтому я подумал, что просто пойду более избыточным путем и просто расширим IntegerType
напрямую (а затем повторю код для FloatingPointType
).
extension IntegerType {
var seconds:NSTimeInterval {
return NSTimeInterval(self)
}
}
Возникшая ошибка сбивает с толку:
Playground execution failed: /var/folders/2k/6y8rslzn1m95gjpg534j7v8jzr03tz/T/./lldb/9325/playground131.swift:31:10: error: cannot invoke initializer for type 'NSTimeInterval' with an argument list of type '(Self)'
return NSTimeInterval(self)
^
/var/folders/2k/6y8rslzn1m95gjpg534j7v8jzr03tz/T/./lldb/9325/playground131.swift:31:10: note: overloads for 'NSTimeInterval' exist with these partially matching parameter lists: (Double), (UInt8), (Int8), (UInt16), (Int16), (UInt32), (Int32), (UInt64), (Int64), (UInt), (Int), (Float), (Float80), (String), (CGFloat), (NSNumber)
return NSTimeInterval(self)
Что меня смущает, так это то, что, кажется, я не могу выполнить инициализатор NSTimeInterval() с (Self), но все, что представляет Self, перечислено в следующей строке, где показаны все возможные инициализаторы NSTimeInterval. Что мне здесь не хватает?
Кроме того: мне бы очень хотелось, чтобы было хорошо написанное руководство по системе типов Swift и тому, как делать подобные вещи. Элементы среднего и продвинутого уровня просто недостаточно подробно описаны в скудной документации Apple по Swift
Обновление/уточнение:
Я хочу иметь возможность оценить любое из приведенных выше выражений:
42.seconds --> 42
3.14.minutes --> 188.4
0.5.hours --> 1800
13.days --> 1123200
Кроме того, я хочу, чтобы тип возвращаемого значения был NSTimeInterval (псевдоним типа для Double), так что:
42.seconds is NSTimeInterval --> true
3.14.minutes is NSTimeInterval --> true
0.5.hours is NSTimeInterval --> true
13.days is NSTimeInterval --> true
Я знаю, что могу добиться этого, просто расширив Double
и Int
как таковые:
extension Int {
var seconds:NSTimeInterval {
return NSTimeInterval(self)
}
var minutes:NSTimeInterval {
return NSTimeInterval(self * 60)
}
var hours:NSTimeInterval {
return NSTimeInterval(self * 3600)
}
var days:NSTimeInterval {
return NSTimeInterval(self * 3600 * 24)
}
}
extension Double {
var seconds:NSTimeInterval {
return NSTimeInterval(self)
}
var minutes:NSTimeInterval {
return NSTimeInterval(self * 60)
}
var hours:NSTimeInterval {
return NSTimeInterval(self * 3600)
}
var days:NSTimeInterval {
return NSTimeInterval(self * 3600 * 24)
}
}
Но я также хотел бы, чтобы следующее выражение работало:
let foo:Uint = 4242
foo.minutes --> 254520
foo.minutes is NSTimeInterval --> true
Это не сработает, потому что я расширил только Int
, а не UInt
. Я мог избыточно расширить Uint
, затем UInt16
, а затем Int16
и т. д....
Я хотел обобщить расширение Int
до IntegerType
, как показано в исходном листинге, чтобы я мог просто получить преобразования для всех целочисленных типов. Затем сделайте то же самое для FloatingPointType
, а не конкретно для Double
. Однако это приводит к исходной ошибке. Я хочу знать, почему я не могу расширить IntegerType, как обычно показано. Существуют ли другие приемщики IntegerType
, отличные от показанных в списке, которые делают так, что инициализатор NSTimeInterval() не разрешается?