描述我想要的东西的最好方法是这个例子:
protocol Lerpable {
// here should be 'lerp<T: Lerpable>(_ x: CGFloat, _ a: T, _ b: T) -> T' function
}
extension CGFloat: Lerpable {}
extension CGPoint: Lerpable {}
extension CGRect: Lerpable {}
func lerp(_ x: CGFloat, _ a: CGFloat, _ b: CGFloat) -> CGFloat {
return a * (1.0 - x) + b * x
}
func lerp(_ x: CGFloat, _ a: CGPoint, _ b: CGPoint) -> CGPoint {
return CGPoint(x: lerp(x, a.x, b.x), y: lerp(x, a.y, b.y))
}
func lerp(_ x: CGFloat, _ a: CGRect, _ b: CGRect) -> CGRect {
return CGRect(x: lerp(x, a.x, b.x), y: lerp(x, a.y, b.y), width: lerp(x, a.width, b.width), height: lerp(x, a.height, b.height))
}
func lerpKeyframes<T: Lerpable>(_ x: CGFloat, array: [T]) -> T? {
if x <= 0 {
return array.first
}
else if x >= (array.count - 1) {
return array.last
}
else {
let leftBound = Int(x)
let fraction = fmod(x, 1.0)
return lerp(fraction, array[leftBound], array[leftBound + 1]) // ERROR here, can't recognize implemented 'lerp' method
}
}
如何编写此代码,以便lerpKeyframes(...)
CGFloat
,CGPoint
和CGRect
使用$(function () {
var ActivityLogViewModel = function () {
self = this;
self.activityLogs = ko.observableArray([]); //data
getData();
console.log(self.activityLogs()); // when this is here, it goes into infinite loop
function getData() {
$.ajax({
type: "GET",
url: "/api/EnvironmentsApi/activityLogs",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
console.log(data);
self.activityLogs(data);
console.log(self.activityLogs());
},
error: function (error) {
alert(error.status + "<--and--> " + error.statusText);
}
});
}
return {
self: self
}
};
ko.applyBindings(ActivityLogViewModel);
});
?
答案 0 :(得分:4)
这是具有相关自我要求的协议的来源。这是一个粗略的例子:
import Foundation
protocol LinearlyInterpolatable {
func interpolate(with: Self, by: CGFloat) -> Self;
}
extension CGFloat: LinearlyInterpolatable {
func interpolate(with other: CGFloat, by k: CGFloat) -> CGFloat {
return self * (1.0 - k) + other * k
}
}
extension CGPoint: LinearlyInterpolatable {
func interpolate(with other: CGPoint, by k: CGFloat) -> CGPoint {
return CGPoint(
x: self.x.interpolate(with: other.x, by: k),
y: self.y.interpolate(with: other.y, by: k)
)
}
}
extension CGRect: LinearlyInterpolatable {
internal func interpolate(with other: CGRect, by k: CGFloat) -> CGRect {
return CGRect(
x: self.x.interpolate(with: other.x, by: k),
y: self.y.interpolate(with: other.y, by: k),
width: self.width.interpolate(with: other.width, by: k),
height: self.height.interpolate(with: other.height, by: k)
)
}
}
func lerpKeyframes<T: LinearlyInterpolatable>(_ k: CGFloat, array: [T]) -> T? {
let leftBound = Int(k)
guard 0 <= leftBound else { return array.first }
guard leftBound < array.count else { return array.last }
let fraction = fmod(k, 1.0)
return array[leftBound].interpolate(with: array[leftBound + 1], by: fraction)
}