【问题标题】:Referring to a type in another module with the same name as a type in the current module when the other module has a type with its own name in Swift当另一个模块在 Swift 中具有具有自己名称的类型时,引用另一个模块中的类型与当前模块中的类型同名
【发布时间】:2021-08-11 03:42:52
【问题描述】:

我正在使用 swift 包管理器。 我有一个模块ModuleA,它导出两种类型:ModuleATest。 我有一个模块ModuleB,它定义了一个类型:Test。 在ModuleB 中,如何从ModuleA 引用类型Test? 理想情况下,我希望 #module(ModuleA) 等语法直接引用模块 ModuleA

可重现的例子:

Package.swift:

// swift-tools-version:5.3

import PackageDescription

let package = Package(
    name: "ShadowingTest",
    products: [
        .library(
            name: "ModuleA",
            targets: ["ModuleA"]),
        .library(
            name: "ModuleB",
            targets: ["ModuleB"]),
    ],
    dependencies: [
    ],
    targets: [
        .target(
            name: "ModuleA",
            dependencies: []),
        .target(
            name: "ModuleB",
            dependencies: ["ModuleA"]),
    ]
)

Sources/ModuleA/ModuleA.swift:

public enum ModuleA {}
public struct Test {
    public static let module: String = "ModuleA"
}

Sources/ModuleB/ModuleB.swift:

import ModuleA

struct Test {
    static let module: String = "ModuleB"
}

func test() {
    print(ModuleA.Test.module)
}

运行swift build 出现错误

Sources/ModuleB/ModuleB.swift:8:19: error: type 'ModuleA' has no member 'Test'

但是当从ModuleA 中的ModuleA 枚举中删除public 时会成功。

【问题讨论】:

    标签: swift swiftpm


    【解决方案1】:

    问题是 ModuleA 模块中的 ModuleA 枚举没有 Test

    当您在ModuleA enum 中删除public 时,ModuleB 无法识别ModuleA enum,因为它的访问修饰符默认为internal,因此ModuleB 识别Test 结构中的ModuleA 而不是试图在ModuleA enum中找到Test


    奖励:SO 中有一个关于访问修饰符的answer,我认为您会发现它很有用。


    编辑:

    如果您需要使用ModuleA.Test,即使有一个名为ModuleA 的枚举,您也可以使用import (class|struct|func|protocol|enum) <needed_component>,因此您应该像这样导入:

    import struct ModuleA.Test
    

    如果你想使用其他名称的结构来避免命名冲突,那么你可以设置一个 typealias ->

    import struct ModuleA.Test
    
    typealias TestA = ModuleA.Test
    

    【讨论】:

    • 我了解访问修饰符在做什么,但这并不能回答我的问题。我的问题是如果模块ModuleA 导出ModuleA 类型,我无法从模块ModuleA 访问Test 类型。如果没有这种类型,ModuleA.Test 指的是来自模块ModuleATest 类型,但如果有这种类型,ModuleA.Test 指的是来自枚举ModuleA 的静态成员Test模块ModuleA(不存在)。当模块ModuleA 导出类型ModuleA 时,我想从模块ModuleA 访问Test
    • @deaton.dg 我已经更新了我的答案,你能检查一下吗?
    • 这行得通,谢谢!理想情况下,我更喜欢像 #module(ModuleA) 这样的语法来专门指代模块(相应地编辑了问题)。如果这仍然是我正在使用的解决方案,我会在几天内接受这个答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 2019-11-29
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 2014-12-18
    • 2018-12-21
    相关资源
    最近更新 更多