* 내가 읽으려고 내 맘대로 번역한 글.
* 원문 : https://docs.swift.org/swift-book/LanguageGuide/Subscripts.html

 

 

 

 

Subscripts

Classes, structures, and enumerations can define subscripts, which are shortcuts for accessing the member elements of a collection, list, or sequence. You use subscripts to set and retrieve values by index without needing separate methods for setting and retrieval. For example, you access elements in an Array instance as someArray[index] and elements in a Dictionary instance as someDictionary[key].

클래스, 구조체, 열거형은 첨자를 정의할수 있다. 첨자는 collection, list, sequence의 멤버 요소에 접근하는 빠른 방법이다.

값을 설정하고 조회하는데 별도의 메소드 없이 첨자를 사용하여 index에 의해 설정하고 조회할수 있다.

예를 들어, someArray[index] 식으로 배열 인스턴스의 요소에 접근할수 있고,

someDictionary[key] 식으로 dictionary 인스턴스의 요소에 접근할수 있다.

 

You can define multiple subscripts for a single type, and the appropriate subscript overload to use is selected based on the type of index value you pass to the subscript. Subscripts are not limited to a single dimension, and you can define subscripts with multiple input parameters to suit your custom type’s needs.

하나의 유형에 대해 다중 첨자를 정의할수 있고, 너가 첨자에 전달하는 index 값의 타입에 따라서 적절한 첨자 오버로드가 선택된다.

첨자는 하나만 넣을수 있는게 아니라, 너가 정의한 타입의 필요에 따라 다중 입력 매개변수를 정의할수 있다.

 

Subscript Syntax

Subscripts enable you to query instances of a type by writing one or more values in square brackets after the instance name. Their syntax is similar to both instance method syntax and computed property syntax. You write subscript definitions with the subscript keyword, and specify one or more input parameters and a return type, in the same way as instance methods. Unlike instance methods, subscripts can be read-write or read-only. This behavior is communicated by a getter and setter in the same way as for computed properties:

첨자는 인스턴스 이름 뒤에 대괄호를 쓰고 그 안에 하나 이상의 값을 적어서 너가 타입의 인스턴스를 조회할수 있게 한다.

이 문법은 인스턴스 메소드 문법과 계산된 속성 문법과 비슷하다.

subscript 키워드로 첨자를 정의하고, 하나 이상의 입력 매개변수와 리턴 타입을 기술한다 (인스턴스 메소드와 동일한 방식으로)

인스턴스 메소드와 다르게 첨자는 읽기/쓰기 또는 읽기전용이 될수 있다.

이 동작은 계산된 속성과 같은 방식으로 getter 와 setter에 전달된다.

subscript(index: Int) -> Int {
	get {
		// Return an appropriate subscript value here.
	}
	set(newValue) {
		// Perform a suitable setting action here.
	}
}

 

The type of newValue is the same as the return value of the subscript. As with computed properties, you can choose not to specify the setter’s (newValue) parameter. A default parameter called newValue is provided to your setter if you do not provide one yourself.

newValue의 타입은 첨자의 리턴값과 동일하다.

계산된 속성처럼, setter의 newValue 매개변수를 기술하지 않아도 된다.

너가 직접 제공하지 않으면, 기본 매개변수 newValue가 너의 setter에 제공된다.

 

As with read-only computed properties, you can simplify the declaration of a read-only subscript by removing the get keyword and its braces:

읽기전용 계산된 속성처럼, get 키워드와 그 중괄호를 없애서 간단하게 읽기전용 첨자를 선언할수 있다.

subscript(index: Int) -> Int {
	// Return an appropriate subscript value here.
}

 

Here’s an example of a read-only subscript implementation, which defines a TimesTable structure to represent an n-times-table of integers:

여기 읽기전용 첨자 구현의 예제가 있다. TimeTable 구조체를 정의하여 정수의 n-times-table을 표현한다.

(이석우 추가 : 아래의 소스를 보니... 오호 신기하다)

struct TimesTable {
	let multiplier: Int
	subscript(index: Int) -> Int {
		return multiplier * index
	}
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])")
// Prints "six times three is 18"

 

In this example, a new instance of TimesTable is created to represent the three-times-table. This is indicated by passing a value of 3 to the structure’s initializer as the value to use for the instance’s multiplier parameter.

이 예에서, TimeTable의 새로운 인스턴스가 만들어지고, three-times-table을 표현한다.

인스턴스의 muliplier에 3을 넣어서 구조체를 초기화 하여 표시된다.

 

You can query the threeTimesTable instance by calling its subscript, as shown in the call to threeTimesTable[6]. This requests the sixth entry in the three-times-table, which returns a value of 18, or 3 times 6.

threeTimesTable[6] 호출에서 보듯이, threeTimesTable 인스턴스에 첨자를 호출하여 조회할수 있다.

three-times-table에서 6번째 항목을 요청하면, 18 또는 3*6이 리턴된다.

 

NOTE

An n-times-table is based on a fixed mathematical rule. It is not appropriate to set threeTimesTable[someIndex] to a new value, and so the subscript for TimesTable is defined as a read-only subscript.

n-times-table 은 고정된 수학적 규칙에 기반한다.

threeTimesTable[someIndex] 에 새로운 값을 설정하는것은 적절하지 않아서, TimeTable의 첨자는 읽기전용으로 정의되었다.

 

Subscript Usage

The exact meaning of “subscript” depends on the context in which it is used. Subscripts are typically used as a shortcut for accessing the member elements in a collection, list, or sequence. You are free to implement subscripts in the most appropriate way for your particular class or structure’s functionality.

첨자의 정확한 의미는 사용되는 문맥에 달려있다.

첨자는 일반적으로 collection, list, sequence의 멤버 요소에 접근하는 지름길로 사용된다.

너는 특정 클래스나 구조체의 기능에 대한 가장 적절한 방식으로 첨자를 자유롭게 구현할수 있다.

 

For example, Swift’s Dictionary type implements a subscript to set and retrieve the values stored in a Dictionary instance. You can set a value in a dictionary by providing a key of the dictionary’s key type within subscript brackets, and assigning a value of the dictionary’s value type to the subscript:

예를 들어, swift의 Dictionary 타입은 Dictionary 인스턴스에 저장된 값들을 설정하고 조회하는데 첨자를 구현하였다.

너는 첨자 괄호안에 dictionary 키 타입의 키를 넣고, dictionary의 값 타입을 첨자에 넣어서 값을 설정할수 있다.

var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2

 

The example above defines a variable called numberOfLegs and initializes it with a dictionary literal containing three key-value pairs. The type of the numberOfLegs dictionary is inferred to be [String: Int]. After creating the dictionary, this example uses subscript assignment to add a String key of "bird" and an Int value of 2 to the dictionary.

For more information about Dictionary subscripting, see Accessing and Modifying a Dictionary.

위의 예는 numberOfLegs 라는 변수를 정의하고, 3개의 키-값 쌍을 포함하는 dictionary 리터럴로 초기화 하였다.

numberOfLegs dictionary의 타입은 [String: Int] 로 추론된다.

dictionary가 생성된후, 이 예제는 첨자 할당을 사용해서 dictionary에 "bird" 라는 문자열 키와 2 숫자 값을 넣었다.

 

NOTE

Swift’s Dictionary type implements its key-value subscripting as a subscript that takes and returns an optional type. For the numberOfLegs dictionary above, the key-value subscript takes and returns a value of type Int?, or “optional int”. The Dictionary type uses an optional subscript type to model the fact that not every key will have a value, and to give a way to delete a value for a key by assigning a nil value for that key.

swift의 Dictionary 타입은 키-값 첨자를 구현하여 optional 타입을 받아들이고 리턴한다.

위의 numberOfLegs dictionary 에서, 키-값 첨자는 Int? 또는 optional int 를 받아들이고 리턴한다.

Dictionary 타입은 optional 첨자를 사용하여 모든 키가 값을 가지는 것은 아니라는 사실을 모델링하고,

키에 nil 값을 할당하여 키 값을 살제하는 방법을 제공한다.

 

Subscript Options

Subscripts can take any number of input parameters, and these input parameters can be of any type. Subscripts can also return any type. Subscripts can use variadic parameters and provide default parameter values, but they can’t use in-out parameters.

첨자는 여러개의 입력 매개변수를 취할수 있고, 어떤 타입도 될수 있다.

첨자는 또한 어떤 타입이라도 리턴할수 있다.

첨자는 가변 매개변수를 사용할수 있고, 기본 매개변수 값을 제공할수 있지만, in-out 매개변수는 사용할수 없다.

 

A class or structure can provide as many subscript implementations as it needs, and the appropriate subscript to be used will be inferred based on the types of the value or values that are contained within the subscript brackets at the point that the subscript is used. This definition of multiple subscripts is known as subscript overloading.

클래스나 구조체는 필요한만큼 많은 첨자 구현을 제공할수 있고,

사용되는 적절한 첨자는 값의 타입이나 첨자가 사용되는 시점에 첨자 괄호안에 포함된 값에 따라서 유추된다.

첨자를 여러개 정의하는것을 첨자 overloading이라고 한다.

 

While it is most common for a subscript to take a single parameter, you can also define a subscript with multiple parameters if it is appropriate for your type. The following example defines a Matrix structure, which represents a two-dimensional matrix of Double values. The Matrix structure’s subscript takes two integer parameters:

첨자가 하나의 매개변수를 받는게 일반적이지만, 너의 타입에 적절한 다중 매개변수를 첨자로 정의할수도 있다.

다음의 예제는 Matrix 구조체를 정의하고, Double 값의 2차원 행렬을 표현한다.

Matrix 구조체의 점자는 2개의 정수 매개변수를 받는다.

struct Matrix {
	let rows: Int, columns: Int
	var grid: [Double]
	init(rows: Int, columns: Int) {
		self.rows = rows
		self.columns = columns
		grid = Array(repeating: 0.0, count: rows * columns)
	}
	func indexIsValid(row: Int, column: Int) -> Bool {
		return row >= 0 && row < rows && column >= 0 && column < columns
	}
	subscript(row: Int, column: Int) -> Double {
		get {
			assert(indexIsValid(row: row, column: column), "Index out of range")
			return grid[(row * columns) + column]
		}
		set {
			assert(indexIsValid(row: row, column: column), "Index out of range")
			grid[(row * columns) + column] = newValue
		}
	}
}

 

Matrix provides an initializer that takes two parameters called rows and columns, and creates an array that is large enough to store rows * columns values of type Double. Each position in the matrix is given an initial value of 0.0. To achieve this, the array’s size, and an initial cell value of 0.0, are passed to an array initializer that creates and initializes a new array of the correct size. This initializer is described in more detail in Creating an Array with a Default Value.

Matrix는 rows, columns 매개변수를 받는 초기화를 제공하고, Double 타입의 rows * columns 를 저장하기 충분한 배열을 만든다.

행렬의 각 위치는 0.0 으로 초기화 되었다. 이를 위해 배열의 크기와 초기값 0.0 이 배열의 초기화에 전달되었고,

올바른 크기의 새로운 배열을 만들고 초기화 하였다.

 

You can construct a new Matrix instance by passing an appropriate row and column count to its initializer:

너는 적절한 열과 행 갯수를 초기화에 전달하여 새로운 Matrix 인스턴스를 생성할수 있다.

var matrix = Matrix(rows: 2, columns: 2)

 

The example above creates a new Matrix instance with two rows and two columns. The grid array for this Matrix instance is effectively a flattened version of the matrix, as read from top left to bottom right:

위의 예제는 2개의 행과 2개의 열을 가지는 새로운 Matrix 인스턴스를 만든다.

이 Matrix 인스턴스를 위한 grid 배열은 좌상단에서 시작해 우하단으로 읽는 행렬을 한줄로 평평하게 만든 버젼이다.

 

Values in the matrix can be set by passing row and column values into the subscript, separated by a comma:

행렬의 값은 행과 열값을 첨자에 넣고 콤마로 구분하여 설정할수 있다.

matrix[0, 1] = 1.5
matrix[1, 0] = 3.2

 

These two statements call the subscript’s setter to set a value of 1.5 in the top right position of the matrix (where row is 0 and column is 1), and 3.2 in the bottom left position (where rowis 1 and column is 0):

이 2개의 문장은 첨자의 setter를 호출하여 우상단에 1.5 좌하단에 3.2를 설정한다.

 

The Matrix subscript’s getter and setter both contain an assertion to check that the subscript’s row and column values are valid. To assist with these assertions, Matrix includes a convenience method called indexIsValid(row:column:), which checks whether the requested row and column are inside the bounds of the matrix:

Matrix 첨자의 getter와 setter 모두 첨자의 열과 행값이 올바른지 검사하기 위하여 assertion을 포함하고 있다.

이러한 assertions을 지원하기 위해, Maxtrix 는 indexIsValid(row:column:)라는 편리한 메소드를 포함해서,

요청된 행과 열이 행렬의 범위 안에 있는지 검사한다.

func indexIsValid(row: Int, column: Int) -> Bool {
	return row >= 0 && row < rows && column >= 0 && column < columns
}

 

An assertion is triggered if you try to access a subscript that is outside of the matrix bounds:

만약 행렬 범위 밖의 첨자에 접근하려 하면 assertion이 발동된다.

let someValue = matrix[2, 2]
// This triggers an assert, because [2, 2] is outside of the matrix bounds.

 

Type Subscripts

Instance subscripts, as described above, are subscripts that you call on an instance of a particular type. You can also define subscripts that are called on the type itself. This kind of subscript is called a type subscript. You indicate a type subscript by writing the static keyword before the subscript keyword. Classes can use the class keyword instead, to allow subclasses to override the superclass’s implementation of that subscript. The example below shows how you define and call a type subscript:

위에서 설명한대로, 인스턴스 첨자는 특정타입의 인스턴에 호출할수 있다.

타입 자체에 호출할수 있는 첨자도 역시 정의할수 있다.

이러한 첨자를 타입 첨자라고 한다.

subscript 키워드 앞에 static 키워드를 적어서 타입 첨자를 나타낸다.

클래스는 대신 class 키워드를 사용해서, 서브 클래스가 부모클래스의 첨자 구현을 덮어쓸수 있도록 할수 있다.

아래 예제는 타입 첨자를 선언하고 호출하는 법을 보여준다.

enum Planet: Int {
	case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
	static subscript(n: Int) -> Planet {
		return Planet(rawValue: n)!
	}
}
let mars = Planet[4]
print(mars)
반응형

'iOS 초보' 카테고리의 다른 글

[swift5.1번역] 14.Initialization  (0) 2019.09.04
[swift5.1번역] 13.Inheritance  (0) 2019.08.27
[swift5.1번역] 11.Methods  (0) 2019.08.19
[swift5.1번역] 10.Properties  (0) 2019.08.14
[swift5.1번역] 9.Structures and Classes  (0) 2019.08.07
Posted by 돌비
,