Как я могу устранить проблему с типом и модулем с тем же именем?
Я пытаюсь использовать Károly Lőrentey B-tree 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
.
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
?
Ответы
Ответ 1
Тип можно устранить с помощью синтаксиса (крайне малоизвестного) import (class|struct|func|protocol|enum) Module.Symbol
.
import struct BTree.OrderedSet
С этого момента OrderedSet недвусмысленно ссылается на значение в BTree.
Если в некоторых файлах это будет неоднозначно или субоптимально, вы можете создать файл Swift для переименования импорта с помощью typealiases:
// 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 появился новый синтаксис, но он провалился.
Ответ 2
Я переименовал OrderedSet
в SortedSet
в версию Swift 3 BTree
, которая должна служить обходным решением, пока возможно исправление языкового уровня обсуждается/реализуется.