Ссылка на объекты в Swift - PullRequest
0 голосов
/ 08 мая 2018

Я новичок в Swift, и я совсем не программировал в последнее время. Я пытаюсь присвоить массив из массива массивов переменной. Но, насколько я могу судить, я получаю только копию этого массива (так что, если член массива массивов впоследствии изменится, копия не изменится. Как получить ссылку на исходный объект?

Вот некоторый код (включенный перед "class ViewController: UIViewController" в попытке получить глобальные переменные):

var g1 = [2,0,0,0,0]
var g2 = [2,0,0,0,0]
var g3 = [2,0,0,0,0]
var g4 = [3,0,0,0,0]
var g5 = [3,0,0,0,0]
var g6 = [4,0,0,0,0]
var g7 = [5,0,0,0,0]

let groids: Array = [g1, g2, g3, g4, g5, g6, g7]

Позже, как часть какой-то функции, я хочу назначить переменную "a" одному из членов groids, но, как я уже сказал, не копию этого члена, а сам этот член. Как мне это сделать? Пожалуйста, помните, что у меня мало опыта программирования.

Ответы [ 3 ]

0 голосов
/ 08 мая 2018

Итак, вы хотите изменить элемент в groids и отразить это изменение в массивах g1-7?

groids[3] = [1,2,3,4,5]
// g4 now becomes [1,2,3,4,5]

Ну, во-первых, groids - это константа, поэтому вы не можете изменить ее. Давайте предположим, что вы изменили его на var.

На самом деле, вам вообще не нужно g1-7. Вы можете удалить эти переменные и просто объявить groids следующим образом:

var groids = [
    [2,0,0,0,0],
    [2,0,0,0,0],
    [2,0,0,0,0],
    [3,0,0,0,0],
    [3,0,0,0,0],
    [4,0,0,0,0],
    [5,0,0,0,0],
]

И вы можете получить доступ от g1 до g7, набрав groids[0] до groids[6].

Вы также можете объявить g1 до g7 как вычисленные свойства, но я не вижу особого смысла в этом:

var g1: [Int] {
    return groids[0]
}

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

0 голосов
/ 08 мая 2018

Есть несколько вещей, которые я считаю проблематичными в вашем коде. Во-первых, groids - это let, что означает, что это константа, поэтому она не будет изменяемой. в swift var используется для обозначения переменных, а let используется для обозначения констант. Во-вторых, глобальные переменные редко желательны, и их следует избегать без веской причины, поэтому убедитесь, что вам действительно нужны глобальные переменные , поскольку они известны тем, что вызывают нежелательные побочные эффекты и делают функциональность кода неясной , и если вы хотите, чтобы они быть глобальными, они должны иметь префикс публичной статики, чтобы все имели к ним доступ. также про передачу по значению объектов говорят о здесь . Что касается разрешения var a = some global, я бы предложил инициализировать groid как единственный глобальный объект, если он действительно должен быть глобальным, а затем использовать его индексы для доступа к различным внутренним массивам. Одно из возможных решений:

let g1:[Int] = [2,0,0,0,0]
let g2:[Int] = [2,0,0,0,0]
let g3:[Int] = [2,0,0,0,0]
let g4:[Int] = [3,0,0,0,0]
let g5:[Int] = [3,0,0,0,0]
let g6:[Int] = [4,0,0,0,0]
let g7:[Int] = [5,0,0,0,0]

public static var groids:[[Int]] = [g1, g2, g3, g4, g5, g6, g7]

//In the place a is assigned
var a:[Int] = groids[0]

Или вместо "a" просто используйте groids, потому что он глобальный, так что вы знаете, что всегда обращаетесь к одной и той же переменной или массиву.

0 голосов
/ 08 мая 2018

Вы не получаете ссылку на «оригинальный объект», потому что в Swift массивы не являются ссылочными типами; они являются типами значений. Это означает, что они действуют так, как будто они всегда копируются. (Под капотом все реализовано более эффективно, но дизайн таков, что они всегда копируются.)

Если ваш единственный предшествующий опыт работы с языками, которые рассматривают массивы как ссылочные типы (что означает почти все популярные языки, такие как C, C ++, C #, Java, Python, Ruby, JavaScript и т. Д.), Это может занять некоторое время, чтобы привыкнуть.

Вот несколько альтернатив:

  1. Используйте NSArray вместо Array. NSArray является ссылочным типом.

  2. Передайте интересующие вас индексы массива или KeyPath. KeyPath задокументировано на языке программирования Swift .

  3. Используйте inout аргументы, которые также документированы в Язык программирования Swift .

...