메모리공간에 순차적으로 동일한 type의 데이터를 연속적으로 할당함. (Zero based array)
var a [N]int
다양한 초기화
package main
// https://play.golang.org/p/UoR8ozvEAO_O
import (
"fmt"
)
func main() {
var a [3]int //정수형 3개 요소를 갖는 배열 a 선언
a[0] = 1
a[1] = 2
a[2] = 3
fmt.Println(a[0]) // 1
var a1 = [3]int{1, 2, 3} // 정적 크기
var a2 = [...]int{1, 2, 3} // '...' 자동크기
fmt.Println(a1)
fmt.Println(a2[0])
// 다차원 배열
var a3 = [2][3]int{ // 2행 3열
{1, 2, 3}, //1행 3열 # 여러줄 나열이므로, ' , ' 콤마를 사용.
{4, 5, 6}, //2행 3열
}
fmt.Println(a3[1][2]) // 6
var multiArray [3][4][5]int
multiArray[0][1][2] = 10
fmt.Println(multiArray) // [[[0 0 0 0 0] [0 0 10 0 0] [0 0 0 0 0]....
fmt.Println(multiArray[0][1][2]) // 10
}
배열 순회
for INDEX [, VALUE]:= range ARRAY_NAME { }
for index, value := range array {
fmt.Println(index, value)
}
keyValues := map[string]string{"ㄱ": "김상현", "ㄴ": "남재현"}
for key, value := range keyValues {
fmt.Printf("%s -> %s\n", key, value)
}
range는 하나의 array, slice or map 의 iterates 를 제공해주는 format(예약어)
range 경우 first, second return 이 index, value 이므로, index 를 선언하지않으면 value 로 하여도 index가 나온다. index를 사용하지 않기위해, ' _ ' 를 사용한다
다중 리턴을 제공하는것과 유사한것일까??
배열 복사
배열 변수는 배열 전체를 다나태기 때문에, a = b 를 하면 b의 값 전체가 복사된다.
func main() {
var a1 = [3]int{1, 2, 3} // 정적 크기
var a2 = [...]int{5, 6, 7} // '...' 자동크기
var a3 = [...]int{5, 6, 7, 1,2,3,4,5,56,7,7,78} // '...' 자동크기
fmt.Println(a1)
fmt.Println(a2[0])
a1 = a2
fmt.Println(a1)
a1 = a3
fmt.Println(a1) // cannot use a3 (type [12]int) as type [3]int in assignment
a3 = a1
fmt.Println(a3) // cannot use a1 (type [3]int) as type [12]int in assignment
}
> 슬라이스가 필요한 느낌이 온다..
슬라이스
동적으로 크기가 늘어날수 있는 레퍼런스 타입!!!. 슬라이스는 공간을 할당 하는것이다.
초기화 및 make 함수
VALUENAME := make( [] TYPE, LENGHT[, CAPACITY_INT]_ )
LENGTH : index 로 접근 가능.
CAPACITY : 총 공간의 크기.
CAPACITY는 LENGTH의 배수인가??? - 내부적 알고리즘으로 크기를 지정한다고하는데..
var a []int // 배열과 달리 [ ] 빈값. len == 0
slice := make( []TYPE, LENGHT_INT ) // len(slice)=5
slice2 := make( []TYPE, LENGHT_INT _[, CAPACITY_INT]_ ) // len(slice)=5, cap(slice) = 5
![2018-11-27 1 33 04](https://user-images.githubusercontent.com/9497634/49058871-43461180-f249-11e8-9075-683a4e304330.png)
> 잘 상상이 안된다..
찾아보니, A slice is a descriptor of an array segment.
https://blog.golang.org/go-slices-usage-and-internals
![2018-11-27 1 39 57](https://user-images.githubusercontent.com/9497634/49058987-f3b41580-f249-11e8-80d9-2a2b1cef7c00.png)
### 레퍼런스 타입
- 슬라이스는 배열의 레퍼런스만 알고있다. 하여 슬라이스 assign을 하여, 값을 수정하는경우 원본에 영향이 가게된다.
- 함수 parameter passing 도 마찬가지로, array 를 넘기면 원본 변화가 값복사여서 문제없지만,
slice 를 넘기게되면 레퍼런스타입이라 원본의 변화가 생길수 있다.
### 슬라이스 복사하기
- copy( DST, SRC )
- DST 의 크기만큼만 복사된다. (= SRC가 더 큰경우 짤림)
> 이전에 assign(=) 과 copy 의 차이는 무엇일까?
// destSlice = originSlice //-> originSlice 변화가 온다
copy(destSlice, originSlice)//-> originSlice 변화가 없다.
fmt.Println(destSlice)
destSlice[0] = 100 // destSlice 변화
fmt.Println(originSlice) // assign 과 copy 에 따라 다른결과.
}
### 슬라이스와 용량
- 동적배열을 위해 길이와 용량을 구분하고, Go Runtime 은 정해진 알고리즘에 의해 슬라이승의 용량을 늘린다.
> 어떤 알고리즘인가??
[copy / append complexity](https://stackoverflow.com/questions/15702419/append-complexity) 관련글을 찾게됐고, 여기안에서 여러방식의 re-allocacte 에 대한 구현이 있다.
### 부분 슬라이스 만들기 (== Reslicing)
- SLICE_NAME[ START_INDEX **:** END_INDEX _[: CAPACITY]_ ]
배열
다양한 초기화
배열 순회
for INDEX [, VALUE] := range ARRAY_NAME { }
배열 복사
배열 변수는 배열 전체를 다나태기 때문에, a = b 를 하면 b의 값 전체가 복사된다.
슬라이스
VALUENAME := make( [] TYPE, LENGHT [, CAPACITY_INT]_ ) LENGTH : index 로 접근 가능. CAPACITY : 총 공간의 크기.
슬라이스 값 추가
import ( "fmt" )
func main() { slice := make([]int, 5, 10)
}
func main() { originSlice := []int{10, 11, 12} destSlice := []int{1, 2, 3, 4, 5} fmt.Println(originSlice) fmt.Println(destSlice)
}
fmt.Println("foobar"[1:3]) // "oo" numbers := [5]int{1, 2, 3, 4, 5} fmt.Println(numbers[1:3]) // [2, 3]
commits := map[string]int{ "jamjomja": 3711, "junhong": 2138, "dev.ik": 1908, "ghost": 912, } for name, commitCount := range commits { if(commitCount > 1000){ fmt.Println(name) } } if commitCount, ok := commits["dev.ik"] ;ok { fmt.Println(commitCount) }
//map[jamjomja:3711 junhong:2138 dev.ik:1908 ghost:912] delete(commits, "ghost") fmt.Println(commits) //map[jamjomja:3711 junhong:2138 dev.ik:1908]
func FUNCTION_NAME() { }
func functionName(params PARAM_TYPE) RETURN_TYPE { }
func functionName(params PARAM_TYPE) returnName RETURN_TYPE { returnName = operationResult return }
func functionName(a A_TYPE, b B_TYPE) ( R1_TYPE, R2_TYPE ) { return a+b, a-b }
func functionName(a A_TYPE, b B_TYPE) ( R1_TYPE, R2_TYPE ) { return a+b, a-b }
func main(){ a, _ = functionName(5, 10) // 사용하지 않는경우 }
func functionName(slice ...A_TYPE) R_TYPE { total := 0 for index , value := range slice { total += value } return total }
func main() { fmt.Print(FibonacciRecursion(10)) // 55 }
func FibonacciRecursion(n int) int { if n <= 1 { return n } return FibonacciRecursion(n-1) + FibonacciRecursion(n-2) }
func main() { var copyFib func(n int) int = FibonacciRecursion // copyFib := FibonacciRecursion fmt.Println(copyFib(10)) // 55 }
func(a int){ fmt.Println(a) }(10)
result = func(a int){ // 익명함수도 리턴을 받을수있다. return a*a }(10)