Slices in Objective-C

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // Unlike arrays, NSMutableArray can dynamically change its size.
        // An uninitialized NSMutableArray is nil and has count 0.
        NSMutableArray *s = nil;
        NSLog(@"uninit: %@, isnil: %@, count: %lu", s, s == nil ? @"YES" : @"NO", s.count);

        // To create an empty array with non-zero length, we can initialize it with a capacity.
        s = [NSMutableArray arrayWithCapacity:3];
        NSLog(@"emp: %@, count: %lu, capacity: %lu", s, s.count, s.capacity);

        // We can set and get just like with arrays.
        [s addObject:@"a"];
        [s addObject:@"b"];
        [s addObject:@"c"];
        NSLog(@"set: %@", s);
        NSLog(@"get: %@", s[2]);

        // count returns the length of the array as expected.
        NSLog(@"len: %lu", s.count);

        // We can add new elements to the array.
        [s addObject:@"d"];
        [s addObjectsFromArray:@[@"e", @"f"]];
        NSLog(@"apd: %@", s);

        // Arrays can also be copied. Here we create a new array and copy into it from s.
        NSMutableArray *c = [NSMutableArray arrayWithArray:s];
        NSLog(@"cpy: %@", c);

        // We can get a slice of the array using NSRange.
        NSRange range = NSMakeRange(2, 3);
        NSArray *l = [s subarrayWithRange:range];
        NSLog(@"sl1: %@", l);

        // This gets a slice up to (but excluding) index 5.
        l = [s subarrayWithRange:NSMakeRange(0, 5)];
        NSLog(@"sl2: %@", l);

        // And this gets a slice from index 2 to the end.
        l = [s subarrayWithRange:NSMakeRange(2, s.count - 2)];
        NSLog(@"sl3: %@", l);

        // We can declare and initialize an array in a single line as well.
        NSArray *t = @[@"g", @"h", @"i"];
        NSLog(@"dcl: %@", t);

        // We can compare arrays for equality.
        NSArray *t2 = @[@"g", @"h", @"i"];
        if ([t isEqualToArray:t2]) {
            NSLog(@"t == t2");
        }

        // Arrays can be composed into multi-dimensional data structures.
        NSMutableArray *twoD = [NSMutableArray array];
        for (int i = 0; i < 3; i++) {
            NSMutableArray *innerArray = [NSMutableArray array];
            for (int j = 0; j <= i; j++) {
                [innerArray addObject:@(i + j)];
            }
            [twoD addObject:innerArray];
        }
        NSLog(@"2d: %@", twoD);
    }
    return 0;
}

This Objective-C code demonstrates concepts similar to Go’s slices, using NSMutableArray and NSArray. Here’s a breakdown of the key points:

  1. We use NSMutableArray as the closest equivalent to Go’s slices, as it allows dynamic resizing.

  2. Unlike Go, Objective-C doesn’t have a built-in slice syntax. Instead, we use methods like subarrayWithRange: to achieve similar functionality.

  3. The append operation in Go is replicated using addObject: and addObjectsFromArray: methods.

  4. Objective-C uses count instead of len to get the number of elements in an array.

  5. The capacity property is available, similar to Go’s cap.

  6. Array literals in Objective-C use the @[] syntax.

  7. For comparing arrays, we use the isEqualToArray: method instead of Go’s slices.Equal.

  8. Multi-dimensional arrays are created by nesting NSMutableArray instances.

When you run this program, you’ll see output similar to the Go version, demonstrating the various operations on mutable arrays in Objective-C.

Note that Objective-C uses reference counting (or ARC) for memory management, so there’s no need for explicit memory allocation or deallocation as in some other languages.