如何在Swift中获取指向数组的指针(而不是副本)?

时间:2019-02-01 07:48:49

标签: arrays swift pointers

在Swift中,将数组分配给新变量实际上是复制的。例如(如在Array的Apple文档中):

var numbers = [1, 2, 3, 4, 5]
var numbersCopy = numbers
numbers[0] = 100
print(numbers)
// Prints "[100, 2, 3, 4, 5]"
print(numbersCopy)
// Prints "[1, 2, 3, 4, 5]"

实际上如何获得指向同一数组的指针,因此修改元素反映在同一数组中? (这样做的原因是我在另一个类的静态实例中访问,例如“ SomethingManager.sharedInstance.arrayList [aKey]”,我希望将其缩短为分配的指针变量。)

(我很想知道如何在Swift 4和5中做到这一点。我没有看到任何有关Swift语言的问题。)

编辑:

我提供的理由是需要一个指针而不是一个副本。

说,我有以下代码:

var childrenTasks = [Int64: [TaskRef]]()

在类中定义,可以访问:

MyClass.singleton.parentTask[parentTaskID].childrenTask[taskRefID]

如您所见,访问childrenTask的代码很长。我想要一个指针,仅是一个例子:-

var aPointerToChildrenTasks = MyClass.singleton.parentTask[parentTaskID].childrenTask[taskRefID] // I want a pointer, not a copy!
aPointerToChildrenTask.remove(at: anIndex) // if it is a pointer, I can manipulate the same set of values of the array

这将有助于使我的代码更易于阅读。我需要一个指针来操作相同的一组值,所以我使用“ var”。如果它是只读的,则可以使用“ let”,但是如果获得副本,它仍然会降低性能。

如何在Swift中获取指针?这可能吗? (我知道在Kotlin中这是可行的,因为它是传递参考。)

编辑:我看到一些建议,这个问题是重复的。不它不是。这些其他问题/答案专门针对inout参数。就我而言,我只希望指针在相同的函数/方法中工作。

2 个答案:

答案 0 :(得分:10)

这不是一个“纯粹的” Swift解决方案,但是使用NSArray将为您提供所需的参考语义。

NSArray是免费的,可以桥接到Array,因此您可以使用普通的as而不是as!

var numbers = [1, 2, 3, 4, 5]
var numbersCopy = numbers as NSArray
numbers[0] = 100
print(numbers)
  

[100,2,3,4,5]

print(numbersCopy as Array)
  

[1、2、3、4、5]

如果您要修改“副本”,则需要使用NSMutableArray

编辑: 哎呀   我想我对您的变量numbersCopy的命名感到困惑。现在,我看到您希望“副本”与原始共享相同的值。通过将变量numbers捕获到一个块中,然后在以后执行该块,可以获得numbers的当前值,而您根本不需要使用NSArray。

var numbers = [1, 2, 3, 4, 5]
var numbersCopy = {numbers}
numbers[0] = 100
print(numbers)
  

[100,2,3,4,5]

print(numbersCopy())
  

[100,2,3,4,5]

答案 1 :(得分:1)

如果只是为了方便起见 ,请考虑使实用程序功能如下:

Map<String, Map<String, List<String>>> map = new HashMap<>();

    neighborhoods.forEach(neighborhood -> {

        Map<String, List<String>> m = map.computeIfAbsent(neighborhood.getId(), (key) -> new HashMap<>());
        neighborhood.getStreets()
                    .forEach(street -> {
                        m.merge(street.getId(),
                                street.getHouses()
                                      .stream()
                                      .map(House::getId)
                                      .collect(Collectors.toCollection(ArrayList::new)),
                                (oldV, newV) -> {
                                    oldV.addAll(newV);
                                    return oldV;
                                }
                        );
                    });
    });

您无法创建“ inout var”,但始终可以进行一个接受func withChildrenTasks(of parentTaskID: Int64, taskRefID: TaskRef, body: (inout [TaskRef]) -> ()) { body(&MyClass.singleton.parentTask[parentTaskID].childrenTasks[taskRefID]) } withChildrenTasks(of: parentTaskID, taskRefID: taskRefID) { tasks in // do stuff with tasks } 参数的回调,因此这是一个简单的解决方法。我希望Swift编译器可以很好地优化它。

如果是因为您实际上要共享数组引用,则可能需要将其包装为引用类型(inout足以满足此目的),或者可以使用class SharedArray<T> { var array = [T]() }基金会。