Skip to content

Apple 官方 Swift 教程 The Swift Programming Language 中文版翻译探讨(1) #2

Description

@pmtao

Apple 官方 Swift 教程 The Swift Programming Language 中文版翻译探讨(1)

官方教程地址
中文版翻译地址

访问控制

关于协议遵循的访问控制,中文版表达的含义有两处是有问题值得商榷的,先摘录中英文对比,用例子解读原文的真正含义,再说明中文翻译的问题。

原文摘录

英文原文:

A type can conform to a protocol with a lower access level than the type itself. For example, you can define a public type that can be used in other modules, but whose conformance to an internal protocol can only be used within the internal protocol’s defining module.

The context in which a type conforms to a particular protocol is the minimum of the type’s access level and the protocol’s access level. If a type is public, but a protocol it conforms to is internal, the type’s conformance to that protocol is also internal.

When you write or extend a type to conform to a protocol, you must ensure that the type’s implementation of each protocol requirement has at least the same access level as the type’s conformance to that protocol. For example, if a public type conforms to an internal protocol, the type’s implementation of each protocol requirement must be at least “internal”.

中文翻译(主要问题出在第二段、第三段):

类型可以遵循更低访问级别的协议。例如,你可以定义一个可在其他模块使用的 public 类型,但它就只能在定义模块中使用如果遵循一个 internal 的协议。

遵循了协议的类的访问级别取这个协议和该类的访问级别的最小者。如果这个类型是 public 级别的,它所遵循的协议是 internal 级别,这个类型就是 internal 级别的。

当你写或是扩张一个类型以遵循协议时,你必须确保该类按协议要求的实现方法与该协议的访问级别一致。例如,一个 public 的类遵循一个 internal 协议,该类的方法实现至少是 “internal” 的。

第二段解读

原文解读

先看以下例子,协议 Math 是 fileprivate 级别,而遵循它的类 SimpleMath 是 public 级别:

// SimpleMath.swift
fileprivate protocol Math {
    func sum(a: Int, b: Int) -> Int
}

public class SimpleMath: Math {
    fileprivate func sum(a: Int, b: Int) -> Int {
        return a + b
    }
}

英文原文的意思是协议遵循这个动作应该在哪个级别的上下文进行(取类型和协议的最小级别),例子中 SimpleMath 这个类是 public 级别,而协议 Math 是 fileprivate 级别,因此 SimpleMath 要遵循 Math 协议的话,上下文的级别只能是更低的那个 fileprivate, 因此在同一个文件中 SimpleMath 类可以遵循 Math 协议。另外补充强调一点,遵循的上下文级别只能取两者最小的那个,但不能比这个还要更小,如果更小则两边的最低级别都无法满足。

但是,如果把协议遵循的代码放到另一个文件中,就不可以,例如拆成以下两个代码,编译器会立即提示错误:Use of undeclared type 'Math',这就说明协议遵循放在了错误的上下文环境里。

// SimpleMath.swift
fileprivate protocol Math {
    func sum(a: Int, b: Int) -> Int
}

public class SimpleMath: Math {
}

// SimpleMath+Extension.swift
extension SimpleMath: Math {
    public func sum(a: Int, b: Int) -> Int {
        return a + b
    }
}

翻译问题说明

再看翻译的意思:遵循了协议的类的访问级别取这个协议和该类的访问级别的最小者。如果这个类型是 public 级别的,它所遵循的协议是 internal 级别,这个类型就是 internal 级别的。,按照上面第一个例子,SimpleMath 类遵循完 Math 协议后就变成 fileprivate 级别了,这显然是不符合事实的。SimpleMath 仍然是 public 级别的,只是说要遵循 Math 协议的这个事情是 fileprivate 级别的,这个级别指代的是遵循的这个动作的上下文级别。

再看下原文这句话:the type’s conformance to that protocol is also internal. 提取出语句的主干:conformance is internal,从这个角度看再考虑翻译就不会产生误解了。

第三段解读

原文解读

When you write or extend a type to conform to a protocol, you must ensure that the type’s implementation of each protocol requirement has at least the same access level as the type’s conformance to that protocol. For example, if a public type conforms to an internal protocol, the type’s implementation of each protocol requirement must be at least “internal”.

提炼原文的重点就是:the type’s implementation has at least the same access level as the type’s conformance., 而这个重点拆成两部分就是:at least same level,  as the type’s conformance.,第一部分强调级别是大于等于,第二部分强调 conformance 这个事情,是不是和上面第二段的解读联系上了!指的就是遵循协议的这个动作的级别。所以原文的意思总结一下就是:类型中对协议实现部分的级别,要大于等于遵循的上下文级别,即取类型和协议级别的最小值。

所以看下面的例子就合理了,这段代码是可以通过编译的:

public protocol Math {
    func sum(a: Int, b: Int) -> Int
}

class SimpleMath: Math {
    internal func sum(a: Int, b: Int) -> Int {
        return a + b
    }
}

例子中,Math 协议是 public 级别, SimpleMath 类是 internal 级别,实现的方法 suminternal 级别,取的是前面两者的最小值,这与原文的要求完全相符。

翻译问题说明

看第三段的翻译:你必须确保该类按协议要求的实现方法与该协议的访问级别一致。 。根据上面的解读,实现方法的级别并不是要与协议级别一致,而是与遵循的上下文级别一致,这是翻译出现错误的地方。而且缺少 至少 一致这个限定,实现后的级别可以更高,例如改写一下 sum 方法,实现后由 fileprivate 变成了 public,这是允许的:

public class SimpleMath: Math {
    public func sum(a: Int, b: Int) -> Int {
        return a + b
    }
}

其他问题

第一段中,但它就只能在定义模块中使用如果遵循一个 internal 的协议。 ,这句话也有点不通顺。调整下顺序就好了:但是如果它遵循一个 internal 协议,这个遵循的部分就只能在这个 internal 协议所在的模块中使用

翻译建议

以下是修正后的翻译建议:

一个类型可以遵循比它级别更低的协议。例如,你可以定义一个 public 类型,它能在别的模块中使用,但是如果它遵循一个 internal 协议,这个遵循的部分就只能在这个 internal 协议所在的模块中使用。

遵循协议时的上下文级别是类型和协议中级别最小的那个。如果一个类型是 public, 但它要遵循的协议是 internal,那么这个类型对该协议的遵循上下文就是 internal.

当你编写或扩展一个类型让它遵循一个协议时,你必须确保该类型对协议的每一个要求的实现,至少与遵循协议的上下文级别一致。例如,一个 public 类型遵循一个 internal 协议,这个类型对协议的所有实现至少都是 "internal" 的。

以上探讨可能还有考虑不够周到的地方,如果错误请不吝赐教。

本文原始发布地址: #2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions