当另一个模块在 Swift 中有一个具有自己名称的类型时,引用另一个模块中与当前模块中的类型同名的类型

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 包管理器。 我有一个模块 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'

但当 publicModuleA 中的 ModuleA 枚举中删除时成功。

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

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

中查找 Test

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


编辑:

如果你需要使用 ModuleA.Test 即使有一个名为 ModuleA 的枚举那么你可以使用 import (class|struct|func|protocol|enum) <needed_component> 所以在你的情况下你应该像这样导入:

import struct ModuleA.Test

如果你想使用另一个名称的结构以避免命名冲突,那么你可以设置一个类型别名 ->

import struct ModuleA.Test

typealias TestA = ModuleA.Test