一尘不染

如何区分具有相同名称的类型和模块?

swift

我正在尝试在一个项目中使用KárolyLőrentey的B树OrderedSet。但是,我遇到了一个问题,即我不能声明不合格,OrderedSet<T>因为该名称在Foundation的NSOrderedSet(如OrderedSet在Swift
3中导入的)和BTree的之间发生冲突OrderedSet

let set = OrderedSet<Int>()
// error: 'OrderedSet' is ambiguous for type lookup in this context
// Found this candidate: Foundation.OrderedSet:3:14
// Found this candidate: BTree.OrderedSet:12:15

要解决此冲突,通常可以使用该名称,然后使用即可BTree.OrderedSet<T>。但是,该BTree模块还包含一个名为的类BTree。如果我写的话BTree.OrderedSet,Swift认为我指的OrderedSet是嵌套在该BTree.BTree类型中的名为type的类型。

let set = BTree.OrderedSet<Int>()
// error: reference to generic type 'BTree' requires arguments in <...>

如果不这样做import BTree,我将根本无法使用该BTree名称。

// no import BTree
let set = BTree.OrderedSet<Int>()
// error: use of undeclared type 'BTree'

如何解决BTree类型和BTree模块之间的这种歧义?


阅读 304

收藏
2020-07-07

共1个答案

一尘不染

可以使用鲜为人知的import (class|struct|func|protocol|enum) Module.Symbol语法消除类型的歧义。

import struct BTree.OrderedSet

从这一点开始,OrderedSet明确引用了BTree中的那个。

如果在某些文件中这仍然是模棱两可或次优的,则可以创建一个Swift文件来使用类型别名重命名导入:

// a.swift
import struct BTree.OrderedSet
typealias BTreeOrderedSet<T> = BTree.OrderedSet<T>



// b.swift
let foo = OrderedSet<Int>() // from Foundation
let bar = BTreeOrderedSet<Int>() // from BTree

Swift 3讨论了一种新语法,但失败了。

2020-07-07