앞서 기본 자료형을 살펴 보면서 array를 소개하였다. 이때 소개한 array는 동적 배열이다.
크기가 정해져있지 않고, push와 pop을 사용하여 데이터를 넣고 뺄 수 있었다.
반면 오늘 소개할 정적배열은 크기가 정해져있는 배열로 동적배열과는 사용하는 방법이 조금 다르다.
- 길이가 정해진 배열 (정적)
자료형 [배열크기] array이름
으로 선언- 기본값 : [0,0,...0]
// fixed array 선언 uint[] a; //동적인 배열 uint[4] b; // fixed array // 정적 array도 memory 적어 주어야 함 function getB() public view returns(uint[4] memory) { return b; }
- fixed array는 길이가 정해져 있기 때문에 push, pop 사용 불가
: push 대신 해당 자리에 값을 넣어주는 방법을 사용
: pop 대신 해당 자리에 0값을 넣어줌
: delete는 사용 가능 (delete의 경우 배열의 전체 값이 초기화 됨)// fixed array에서 push 하는 법 (input 2개) function pushB(uint n, uint _n) public{ b[n] = _n; } // fixed array에서 push 하는 법 (input 1개) uint count; function pushB2(uint _n) public { b[count++] = _n; } // delete 사용 법 function pushB2(uint _n) public { delete b; }
- 동적 배열의 경우 :
new 데이터형 [](0)
- 정적 배열의 경우
: 지역변수로 새로운 정적 배열 선언 후 기존 값에 덮어 씌워 사용
: 기존정적배열 =데이터형[크기] memory 변수명
//a는 동적, b는 정적 struct set{ uint[] a; bytes1[4] b; } //set형 배열인 group set[] group; //group 초기값 push function pushSet() public { bytes1[4] memory _b; group.push(set(new uint[](0), _b)); }
가스비 측면에 있어 어떤 값이 더 최적화 되어 있는지 살펴보고자 한다.
uint[] public a; function popA() public { a.pop(); } function deleteA() public { delete a; } function renewA() public { a = new uint[](0); }
🔎 pop vs delete
- array를 초기화 시키기 위해서 delete는 한 번, pop은 여러번 수행하여야 함.
- pop은 같은 양의 cost를 요구하지만 제일 마지막에는 추가적인 gas를 요구함.
- delete는 단일 수행이므로 요구하는 gas가 높으나, 총액으로 환산하면 더 경제적일 수 있음.
🔎 delete vs new
- delete와 new 모두 내부 요소의 개수가 커질수록 cost도 늘어남.
- delete가 전반적으로 gas, transaction, execution cost 모두 낮음. (예외 경우 발생할 수 있음)
struct와 mapping에서도 array를 사용할 수 있다.
값을 설정하고 불러 올 경우 array의 특성을 잘 고려하여야 한다.// Student 구조체 선언 struct Student{ uint number; string name; string [] classes; } // mapping 선언 mapping(string => Student) Teacher_Student; mapping(string => Student[]) Teacher_Class; //value로 array사용
// Teacher_Class[_Teacher]라는 value값에 Student형인 자료를 push function setTeacher_Class( string memory _Teacher, uint _number, string memory _name, string[] memory _classes ) public { Teacher_Class[_Teacher].push(Student(_number,_name,_classes)); } // 배열 형태인 Teacher_Class[_Teacher]값 반환 function getTeacher_Class(string memory _Teacher) public view returns(Student[] memory){ return Teacher_Class[_Teacher]; } // mapping value의 n번째 number값 수정 function set2(string memory _Teacher, uint _n, uint _number) public{ Teacher_Class[_Teacher][_n-1].number = _number; }