swift - 应用程序中可用的框架依赖项的类型扩展

标签 swift frameworks

好吧……这很难解释(也很难想出一个标题),但我会尽力而为。

我们第一次发现这个是在使用 Carthage 导入东西时,但在 Xcode 中设置示例项目(不使用 Carthage)似乎做了同样的事情。

首先,这是我们设置的示例项目的屏幕截图...

enter image description here

有一个目标 Test20000 并且它有一个依赖项 A

A 框架依赖于 B

重要

Test20000 应用B 添加为直接依赖项。

框架

B 中有一个结构,如...

import Foundation

public struct BType {
    public let value = "Hello, B!"
}

A 中有一个文件...

import Foundation
import B

public struct AType {
    public let value = "Hello, A!"

    public func doAThing() {
        print(BType().value)
    }
}

应用

现在在 Test20000 应用程序中,我们做一些类似...

import Foundation
import A

struct TestType {
    func doSomething() {
        let aType = AType()

        print(aType.value)
        aType.doAThing()
    }
}

这按预期工作。它打印...

Hello, A! Hello, B!

如果我把函数改成这样...

import Foundation
import A

struct TestType {
    func doSomething() {
        let bType = BType()

        print(bType.value)
    }
}

然后这不会编译,因为 B 未导入,因此无法访问 BType

捕获了!

但是!如果您在 B 中声明扩展,例如...

extension String {
    func doAThingInB() {
        print(self)
    }
}

然后现在...无需对导入和依赖项进行任何更改,我现在可以将我的应用程序代码更改为...

import Foundation
import A

struct TestType {
    func doSomething() {
        "Hello, bug!".doAThingInB()
    }
}

这将打印出来,就好像扩展对实际应用程序是公开的一样。它有点像 B 的“兔子跳”,越过 A 进入应用程序。

我觉得这根本不应该发生。

我们找不到关闭或阻止这种情况发生的方法。

这是一个错误吗?

我们需要做些什么来阻止这种情况吗?

谢谢

最佳答案

我尝试使用 private module maps隐藏内部框架,使 A 的用户不可见,但没有成功。可能与 [SR-2896] Private modulemaps do no work properly 有关.

我想这是目前预期的行为。 swift.org 论坛上有多个提案可以实现您想要的东西,例如 Namespaces x submodules或更相关的@_exported and fixing import visibility .

上一篇的相关部分:

Today’s Swift is designed more like Java or C# or Python, in that if you import Bar in the implementation of Foo it doesn’t affect clients who import Foo. Or, well, it doesn’t make the top-level names of Bar visible to clients who import Foo.

  1. You still need Bar around, because the compiler doesn’t track whether you’ve used one of its types in Foo’s public interface. (That’s the previous section.)

  2. Extensions in Bar are still made visible to clients who import Foo, because the compiler doesn’t distinguish where extensions come from today.

  3. Operator declarations in Bar are still made visible to clients who import Foo, because the compiler finds operators in a different way than it finds everything else at the top level.

来自最后一条消息:

the general outcome of this discussion is that it's probably not worth doing anything clever for Swift vNext: just add "implementation-only import" and maybe "exported import" and leave the rest alone for now.

我很高兴知道是否有解决方法,但它 seems like没有。

关于swift - 应用程序中可用的框架依赖项的类型扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54653951/

相关文章:

ios - Swift MFMessageComposeViewController 色调和背景色 iOS 10

ios - Swift 模块稳定性 : Module compiled with Swift X. Y 无法被 Swift X.Z 编译器导入

wcf - 为什么我的 oData 服务( Entity Framework )不允许导航属性

php - 如何将 auth::user 配置文件数据存储到 Laravel View 中?

Electron 框架上的 Python

html - Bulma.io 全高英雄背景

swift - 有什么方法可以替换 Swift String 上的字符?

swift - 使用 Haskell 风格快速排序

ios - 指定最小单元格高度会产生警告?

arrays - Swift:具有唯一键和与键匹配的一组值的字符串字典