2015-06-14 2 views
4

Скажем, у меня есть этот код:Swift: кортежи доступа по индексу

let tuples = ("1", 2, "3", "4", "5", "6", "7", false) 

func tableView(tableView:NSTableView, viewForTableColumn tableColumn:NSTableColumn?, row:Int) -> NSView? 
{ 
    let valueForView = tuples[row] 
} 

Есть ли способ получить доступ к наборам по индексу?

+0

Как @ Бен-G сказал, что вы хотите сделать, это невозможно, следует использовать массив вместо. – Arbitur

+0

Как это работает? Тип элемента кортежа зависит от индекса, который должен быть известен во время компиляции. – Clashsoft

ответ

0

То, что вы хотите, невозможно с кортежами, и если вы не хотите, чтобы все было брошено позже, ваш единственный вариант - это структура или класс. структура кажется лучшим выбором :)

struct MyStruct { 
    let opt1 = 0 
    let opt2 = 0 
    let opt3 = 0 
    ... 
    let boolThing = false 
} 
+0

Спасибо, это, кажется, самый полезный ответ. – BadmintonCat

+0

Хороший ответ! Тем не менее, вы, к сожалению, также не сможете сделать этот индексный и безопасный тип :( –

+0

Да, я заметил это и был немного забит с принятием: O Но, возможно, мой ответ дал ОП идею :) – Arbitur

6

Нет, вы можете получить доступ только к элементам кортежа, указав указатель непосредственно, например.

tuples.5 

Для вашей цели вы должны просто использовать массив.

+0

Но этот массив должен быть [AnyObject] для смешанных типов. Кортеж позволял бы печатать доступ к своим значениям. – BadmintonCat

+0

@hexagonstar Пользователь a struct then;) – Arbitur

+0

Интересно, если нет способа расширить Swift Tuple с расширением подстроки? – BadmintonCat

4

Это действительно возможно, если вы готовы сделать обертку вокруг вашего кортежа. Это, как говорится, ужасно, никогда не делайте этого. Предложения, сделанные в других ответах, практически намного лучше, но для целей образования , вот мой пример.

struct TupleWrapper { 
    let tuple: (String, Int, String, String, String, String, String, Bool)  
    let count: Int 
    private let mirrors: [MirrorType] 

    subscript (index: Int) -> Any { 
     return mirrors[index].value 
    } 

    init(tuple: (String, Int, String, String, String, String, String, Bool)) { 
     self.tuple = tuple 

     var mirrors = [MirrorType]() 
     let reflected = reflect(tuple) 

     for i in 0..<reflected.count { 
      mirrors.append(reflected[i].1) 
     } 

     self.mirrors = mirrors 
     self.count = mirrors.count 
    } 
} 

let wrapper = TupleWrapper(tuple: ("1", 2, "3", "4", "5", "6", "7", false)) 
wrapper[0] // "1" 
wrapper[wrapper.count - 1] // false 

Код выше использует API для отражения Свифта, чтобы получить логические ребенок вашего объекта кортежа и добавить свои зеркала в массив, на котором мы можем индекс для значения каждого зеркала. Это довольно прямолинейно, но, как и следовало ожидать, поскольку мы работаем с кортежами, это никоим образом не может быть динамическим. Обертка должна быть создана для определенного типа кортежа.

Для некоторых связанных чтений см. Недавнюю статью NSHipster MirrorType.

+0

Вау, спасибо, но это не тот ответ, который я ищу. Sadly Swift импортирует простой массив C как финский кортеж. –

1

Это вид можно с помощью отражения:

Mirror(reflecting: tuples).children[AnyIndex(row)].value 
Смежные вопросы