如何消除具有相同名称的类型和模块的歧义?

zne*_*eak 37 swift swift3

我正试图在一个项目中使用KárolyLőrentey的B树OrderedSet.但是,我遇到了一个我不能声明不合格的问题,OrderedSet<T>因为名称在Foundation NSOrderedSet(OrderedSet在Swift 3中导入)和BTrees 之间存在冲突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
Run Code Online (Sandbox Code Playgroud)

要解决此冲突,您通常会对该名称进行限定,这样您就可以获得该名称BTree.OrderedSet<T>.但是,该BTree模块还包含一个名为的类BTree.如果我写BTree.OrderedSet,Swift认为我指的是一个名为OrderedSet嵌套在BTree.BTree类型中的类型.

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

如果我不这样做import BTree,我根本不能使用这个BTree名字.

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

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

zne*_*eak 45

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

import struct BTree.OrderedSet
Run Code Online (Sandbox Code Playgroud)

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

如果在某些文件中这仍然是不明确的或次优的,您可以创建一个Swift文件来使用typealiases重命名导入:

// a.swift
import struct BTree.OrderedSet
typealias BTreeOrderedSet<T> = BTree.OrderedSet<T>
Run Code Online (Sandbox Code Playgroud)

 

// b.swift
let foo = OrderedSet<Int>() // from Foundation
let bar = BTreeOrderedSet<Int>() // from BTree
Run Code Online (Sandbox Code Playgroud)

有一个针对Swift 3讨论过的新语法,但它已经失败了.

  • 谢谢!也可以使用`protocol`,`enum`,即导入后定义类型的所有关键字,只导入特定类型. (5认同)

Kar*_*tey 5

我在Swift 3 版本中重命名OrderedSet为,这应该作为一种解决方法,同时正在讨论/实施可能的语言级修复。SortedSetBTree