简体   繁体   中英

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

I am using the swift package manager. I have a module ModuleA which exports two types: ModuleA and Test . I have a module ModuleB which defines a single type: Test . In ModuleB , how can I refer to the type Test from ModuleA ? Ideally, I would like syntax such as #module(ModuleA) to refer directly to the module ModuleA .

Reproducible example:

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)
}

Running swift build errors with

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

but succeeds when public is removed from the ModuleA enum in ModuleA .

the issue is ModuleA enum in ModuleA module does not have Test .

When you remove public in ModuleA enum then ModuleB cannot recognize there is a ModuleA enum because its access modifier is internal by default so ModuleB recognizes Test struct in ModuleA instead of trying to find Test in ModuleA enum


Bonus: There is a answer in SO about access modifiers I think you'll find useful.


EDIT:

If you need to use ModuleA.Test even there is an enum named ModuleA then you can use import (class|struct|func|protocol|enum) <needed_component> so in your case you should import like this:

import struct ModuleA.Test

If you want to use the struct with another name to avoid naming conflicts then you can set a typealias ->

import struct ModuleA.Test

typealias TestA = ModuleA.Test

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM