编译器无法将私有扩展中的方法识别为私有

时间:2018-08-09 14:55:50

标签: swift

我有以下代码:

// using named placeholders
$params = array(
     "param1" => "param1",
     "param2" => "param2",
     "param3" => "param3",
     "param4" => "param4",
     "param5" => "param5"
);
$query = $conn->query = '
    INSERT INTO myTable ("value1", "value2", "value3", "value4", "value5")
    VALUES(:value1, :value2, :value3, :value4, :value5)
';
$query->execute($params);

// using unnamed placeholders
$params = array("param1", "param2", "param3", "param4", "param5");
$query = $conn->query = '
    INSERT INTO myTable ("value1", "value2", "value3", "value4", "value5")
    VALUES(?, ?, ?, ?, ?)
';
$query->execute($params);

如果我使用错误方法class C { private enum E { // ... } } private extension C { func f(e: E) { // error: Method must be declared private because its parameter uses a private type // ... } } ,编译器错误将消失。我想知道这是Swift中的错误还是没有得到什么?

1 个答案:

答案 0 :(得分:3)

在顶层,private等效于fileprivate –因为private表示仅在封闭范围(以及同文件扩展名)内访问,并且在顶层, 文件是那个范围。

所以您在这里所拥有的等同于:

class C {
    private enum E {
        // ...
    }
}

fileprivate extension C {
    // error: Method must be declared private because its parameter uses a private type.
    func f(e: E) { 
        // ...
    }
}

(因此,为了清楚起见,我总是在顶层写fileprivate而不是private

这使问题更容易理解-扩展方法f默认为fileprivate,因此可以在整个文件范围内访问,但是其参数键入为E ,只能在类C的范围内访问。

您已经发现,可以将f标记为private

class C {
  private enum E {
    // ...
  }
}

fileprivate extension C {
  private func f(e: E) {
    // ...
  }
}

或将E标记为fileprivate

class C {
  fileprivate enum E {
    // ...
  }
}

fileprivate extension C {
  func f(e: E) {
    // ...
  }
}

为了解决该问题,以使扩展方法f与参数类型E具有相同的可见性。