Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift-指定与泛型类型参数协议的一致性_Swift_Generics_Swift Protocols_Property Wrapper - Fatal编程技术网

Swift-指定与泛型类型参数协议的一致性

Swift-指定与泛型类型参数协议的一致性,swift,generics,swift-protocols,property-wrapper,Swift,Generics,Swift Protocols,Property Wrapper,我想做的是有两个泛型类型参数,其中一个是特定类型,另一个是协议,如下所示: @propertyWrapper 结构实现,其中T:AnyObject,T:P{//编译器错误 var wrappedValue:P{projectedValue} var projectedValue:T init(u实例:T){ self.projectedValue=实例 } } 这样,可以隐藏实际类型,并且只公开协议 现在这不起作用了,因为p是一种非类、非协议类型,所以t不能被约束到它 有办法解决这个问题吗?我

我想做的是有两个泛型类型参数,其中一个是特定类型,另一个是协议,如下所示:

@propertyWrapper
结构实现,其中T:AnyObject,T:P{//编译器错误
var wrappedValue:P{projectedValue}
var projectedValue:T
init(u实例:T){
self.projectedValue=实例
}
}
这样,可以隐藏实际类型,并且只公开协议

现在这不起作用了,因为
p
是一种非类、非协议类型,所以
t
不能被约束到它


有办法解决这个问题吗?

我认为您可以为T创建一个从中继承的协议,这样您就根本不需要p了:

protocol ImplementationProtocol: AnyObject {}

@propertyWrapper
struct Implementation<T: ImplementationProtocol> { 

    var wrappedValue: ImplementationProtocol { projectedValue }

    var projectedValue: T

    init(_ instance: T) {
        self.projectedValue = instance
    }

}
协议实现协议:AnyObject{}
@房地产经纪人
结构实现{
var wrappedValue:ImplementationProtocol{projectedValue}
var projectedValue:T
init(u实例:T){
self.projectedValue=实例
}
}
现在,您的“T”必须符合“ImplementationProtocol”和“wrappedValue”也必须符合“ImplementationProtocol”,正如您试图在上面的代码中完成的那样

希望能对你有所帮助
@propertyWrapper
struct Implementation<T, P> where T : AnyObject{ 
var wrappedValue: P? = nil

var projectedValue: T {
    didSet {
        if let value =  projectedValue as? P {
                wrappedValue = value
            }
        }
    }

    init(_ instance: T) {
        self.projectedValue = instance
    }

}
结构实现,其中T:AnyObject{ var wrappedValue:P?=nil var projectedValue:T{ 迪塞特{ 如果let值=项目值为?P{ wrappedValue=值 } } } init(u实例:T){ self.projectedValue=实例 } }
您想要的不是该语言的功能,因此最接近您的选项是否定某些属性的运行时解决方案

@propertyWrapper
结构实现{
init(uuProjectedValue:Object)抛出{
如果let error=CastError.Desired(projectedValue,Protocol.self)
{抛出错误}
self.projectedValue=projectedValue
}
var projectedValue:对象
var wrappedValue:Protocol{projectedValue as!Protocol}
}
协议{}
类:协议{init(){}
结构{
@实现var实现:协议
init()抛出{
_implementation=try.init(.init())
}
}
public enum CastError{
///表示无法进行所需转换的错误。
需要公共结构:错误{
///如果'instance'是'DesiredCast',则为'nil'。

///-参数实例:任意。这与我尝试做的不同。您只能将此属性包装器用于
ImplementationProtocol
。好的,我做了一些挖掘,这种方法如何,它并不完美,因为wrappedValue是可空的,但它应该可以工作。这也受到限制,因为无法强制执行
T
也属于
P
类型。它基本上与删除
T
和创建
实例:AnyObject
相同。感谢您的尝试。是的,我想这是我们在当前语言约束下能得到的最接近的结果。太糟糕了:(