为什么我们需要在这里通用?协议不够? [英] Why do we need a generic here? Isn't the protocol enough?
问题描述
我在网上找到了关于将泛型和协议一起使用的例子,但是我不明白为什么我们需要泛型,当我们需要的只是使用协议时。
我们定义了一个协议:
协议Healthy {
mutating func setAlive(status:Bool)
var health:Int {get}
}
然后使用通用adotping协议的函数
func check< T:Healthy>(inout object:T ){
pre>
if(object.health< = 0){
object.setAlive(false)
}
}
我改变了下面的代码,一切都还好。
c $ c> func check(object:inout Healthy){
if(object.health< = 0){
object.setAlive(status:false)
}
}
还是没有?
唯一的原因我可以考虑在那里使用泛型,如果它是一个协议有关联类型,并且它不能用作实例。
他们表达了不同的东西。
func check(object:inout Healthy){
健康
符合实例。因此,您可以这样做:
protocol健康{}
struct Foo:Healthy {}
struct Bar:Healthy {}
func check(object:inout Healthy){
object = Bar()
}
var h :Healthy = Foo()
check(object:& h)
print(h)// Bar()
我们调用 check(object:)
并传入 h
Foo
实例)作为 inout
参数,但以 h $ c $结尾c>持有
Bar
实例。
您会注意到这意味着我们不能简单地调用使用具体类型的
。以下不编译: inout
参数检查(object:)
var h = Foo()
//编译器错误:无法将不可变的值作为inout参数传递:
//从'Foo'到'Healthy'的隐式转换需要临时
检查(object:& h)
因为 check(object:)
可以指定任意 Healthy
将符合实例的对象
参数,不可赋值给 Foo
变量。
但是,使用
func check
现在可以使用具体类型的 (注意 I found the following example on the web about using generics together with protocols, however I don't understand why do we need generics at all, when all we need is to use a protocol. We define a protocol: And then a function using a generic adotping that protocol I've changed the code as below and everything is still fine. Or not? The only reason I could think of to use a generic there, if it's a protocol has an associatedtype and it can't used as an instance. They express different things. With The We called You'll note that this means we cannot simply call Because However, with The This therefore now allows you to call it with a concrete-typed (note So in most cases, you'll likely want to make the method generic rather than having a protocol-typed 这篇关于为什么我们需要在这里通用?协议不够?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! object
参数是符合 Healthy
的一个特定具体类型(并且此类型在呼叫站点处得到满足)。你不能仅仅为它分配一个任意的健康的
符合实例,因为它可能与作为 inout $ c传递的变量类型不兼容
inout
参数来调用它。我们现在可以说:
协议健康状况{
var alive:Bool {get set}
}
struct Foo:Healthy {
var alive:Bool
}
struct Bar:Healthy {
var alive:Bool
}
func check< T:Healthy>(object:inout T){
object.alive = false
//非法
//对象= Bar()
}
var h = Foo(alive:true)
check(object:& h)
h
可以输入为 Foo $ c
因此在大多数情况下,您可能希望使该方法为泛型,而不是使用协议类型为 inout code>参数,因为您可能想要处理具体的类型。
protocol Healthy {
mutating func setAlive(status: Bool)
var health: Int { get }
}
func check<T:Healthy>(inout object: T) {
if (object.health <= 0) {
object.setAlive(false)
}
}
func check( object: inout Healthy) {
if (object.health <= 0) {
object.setAlive(status: false)
}
}
func check(object: inout Healthy) {
object
argument can be any Healthy
conforming instance. Therefore, you could do this:protocol Healthy {}
struct Foo : Healthy {}
struct Bar : Healthy {}
func check(object: inout Healthy) {
object = Bar()
}
var h: Healthy = Foo()
check(object: &h)
print(h) // Bar()
check(object:)
and passed h
(which holds a Foo
instance) as the inout
argument, but ended up with h
holding a Bar
instance.check(object:)
with a concrete-typed inout
argument. The following doesn't compile:var h = Foo()
// compiler error: Cannot pass immutable value as inout argument:
// implicit conversion from 'Foo' to 'Healthy' requires a temporary
check(object: &h)
check(object:)
could assign an arbitrary Healthy
conforming instance to the object
argument, which is not assignable to a Foo
variable.func check<T : Healthy>(object: inout T) {
object
argument is a single specific concrete type that conforms to Healthy
(and this type is satisfied at the call-site). You cannot just assign an arbitrary Healthy
conforming instance to it, as it might not be compatible with the variable type being passed as the inout
argument.inout
argument. We can now say:protocol Healthy {
var alive: Bool { get set }
}
struct Foo : Healthy {
var alive: Bool
}
struct Bar : Healthy {
var alive: Bool
}
func check<T : Healthy>(object: inout T) {
object.alive = false
// illegal
// object = Bar()
}
var h = Foo(alive: true)
check(object: &h)
h
is able to be typed as Foo
)inout
parameter, as you'll likely want to be dealing with concrete types.