#arrays #swift #variable-assignment
#массивы #swift #переменная-назначение
Вопрос:
У меня такой длинный массив:
let array = [1, 2, 3]
и я хочу присвоить значения всех элементов разным переменным следующим образом:
var a, b, c:Int
[a, b, c] = array
Я знаю, что это возможно с кортежами, но мне нужно сделать это с помощью массива и без выполнения каждой переменной по отдельности.
Комментарии:
1. Вопрос в том, зачем вам это нужно? Просто используйте индексы коллекции вместо переменных
2. если у меня есть около 10 переменных, и мне нужно создать функцию для изменения их переменных в соответствии с массивом, как я это делаю, не назначая каждую из них отдельно
3. Просто используйте сам массив. При необходимости вы можете использовать
inout
ключевое слово.4. Для чего вам нужна структура со всеми необходимыми свойствами. Просто.
5. Никогда не бывает слишком поздно. Лучше исправить это сейчас, иначе это приведет к эскалации
Ответ №1:
В списке доступных шаблонов нет «шаблона массива» или чего-то подобного, поэтому вы не можете сопоставить шаблоны с массивами. Однако то, что вы можете сделать, это:
let array = [1,2,3]
let (a, b, c) = (array[0], array[1], array[2])
Это вызовет ошибку во время выполнения, если в массиве меньше 3 элементов.
Ответ №2:
Это полезно, но не встроено. И вариационные дженерики делают это болезненным.
let (a, b, c) = [1, 2, 3].tuple3!
/// A workaround for not being able to extend tuples.
public struct Tuple<Elements> {
public var elements: Elements
public init(_ elements: Elements) {
self.elements = elements
}
}
public extension Tuple {
// MARK: - 2-tuple
/// Create a new tuple with one more element.
static subscript<Element0, Element1, Element2>(
tuple: Elements, element: Element2
) -> (Element0, Element1, Element2)
where Elements == (Element0, Element1) {
(tuple.0, tuple.1, element)
}
// MARK: - 3-tuple
/// Create a new tuple with one more element.
static subscript<Element0, Element1, Element2, Element3>(
tuple: Elements, element: Element3
) -> (Element0, Element1, Element2, Element3)
where Elements == (Element0, Element1, Element2) {
(tuple.0, tuple.1, tuple.2, element)
}
}
public extension Sequence {
typealias Tuple2 = (Element, Element)
typealias Tuple3 = (Element, Element, Element)
typealias Tuple4 = (Element, Element, Element, Element)
var tuple2: Tuple2? { makeTuple2()?.tuple }
var tuple3: Tuple3? { makeTuple3()?.tuple }
var tuple4: Tuple4? { makeTuple4()?.tuple }
private func makeTuple2() -> (
tuple: Tuple2,
getNext: () -> Element?
)? {
var iterator = makeIterator()
let getNext = { iterator.next() }
guard
let _0 = getNext(),
let _1 = getNext()
else { return nil }
return ((_0, _1), getNext)
}
private func makeTuple3() -> (
tuple: Tuple3,
getNext: () -> Element?
)? {
guard
let (tuple, getNext) = makeTuple2(),
let element = getNext()
else { return nil }
return (Tuple[tuple, element], getNext)
}
private func makeTuple4() -> (
tuple: Tuple4,
getNext: () -> Element?
)? {
guard
let (tuple, getNext) = makeTuple3(),
let element = getNext()
else { return nil }
return (Tuple[tuple, element], getNext)
}
}
Комментарии:
1. Вы действительно предлагаете что-то подобное?
2. Да. Это должно быть в стандартной библиотеке.