Typescript - 14

이강민·2022년 7월 21일
0

Typescript

목록 보기
14/16
post-thumbnail

Typescript - 14

반복기(iterator) 이해하기

반복기와 반복기 제공자

앞서 for 구문을 살펴본 바와 같이 반복기를 이미 경험해 보았다.
반복기의 특징은 다음과 같다.

  • next라는 이름의 메서드를 제공한다.
  • next 메서드는 value와 done이라는 두 개의 속성을 가진 객체를 반환한다.

다음 함수를 만들어서 반복기 제공자(iterable)를 만들어 보자

//number 타입의 from과 to를 받아서 
export const createRangeIterable = (from : number, to:num
{
  //아래 변수에 from 매개 변수를 넣고 
 let currentValue = from
  return {
    //nuxt메서드를 실행하는데
    next(){
      // value에는 currentValue가 to보다 작으면 1증가, 크면 undefined를 반환한다.
      const value = currentValue < to ? currentValue ++ : undefined
      // 만약 value가 undefined가 되면 done이라는 변수에 넣어서
      const done = value == undefined
      // value와 done을 리턴한다.
      return {value, done}
    }
  }
}

다음과 같이 사용할 수 있다.

import {createRangeIterable} from './export';

//1~3까지 출력하고 싶어서 3을 명시하기 위한 두번째 매개변수의 3 + 1표현
// 아직 next메서드가 실행되지 않기 때문에 동작하지 않는다.
const iterator = createRangeIterable(1,3+1)

while(true){
  // 리턴값을 객체분해할당을 하여 메소드를 실행하도록 한다.
  const {value, done} = iterator.next();
  // 만약 done이 참이라면  break하여 while문을 나간다.
  if(done) break
  // 아니라면 value를 띄운다.
  console.log(value)
}

반복기는 왜 필요 할까?

위의 코드에서 iterator.next 메서드가 반복 호출 될 때마다 각기 다른 값이 출력이 된다. 반복기 제공자가 생성한 값 1,2,3을 배열에 담아서 출력하지 않고 for 문을 돌면서 콘솔 출력문으로 찍어 내듯한 모습이다.
반복기 제공자는 이처럼 어떤 범위의 값을 한번에 생성해서 배열에 담지 않고 값이 필요 할 때만 생성한다. (next 메소드)

for...of 구문과 [Symbol.iterator]메서드

함수로 만들어서 iterator를 for of 문에 사용하면 Symbol객체가 없다는 에러가 발생한다. for of 문을 사용하고 싶으면 [Symbol.iterator]메서드를 구현해야 한다.
클래스로 만들어서 해당 메서드를 구현 할 수 있다.

export class RangeIterable{
  constructor(public from:number, public to:number){

  }
  [Symbol.iterator](){
    const that = this
    let currentValue = that.from
    return {
      next(){
        const value = currentValue < that.to ? currentValue++ : undefined
        const done = value == undefined
        return {value, done}
      }
    }
  }
}

위와 같이 Symbol.iterator메서드를 클래스로 구현하고 아래에 사용하면 잘 되는 것을 확인 할 수 있다.

import {RangeIterable} from './range'

const iterator = new RangeIterable(1, 3 + 1)

for(let value of iterator)
  console.log(value)

Iterable와 Iterator인터페이스

타입스크립트는 반복자 제공자에 제네릭 인터페이스를 사용할 수 있다.
Iterable는 자신을 구현하는 클래스가 [Symbol.iterator]메서드를 제공한다는 것을 명확하게 알려주는 역할을 한다.

class 구현클래스 implements Iterable<생성할 값의 타입>{ }

또한 제네릭 인터페이스는 반복기가 생성할 값의 타입을 명확하게 해준다.

[Symbol.iterator]( ) : Iterator<생성할 값의 타입> { }
export class StringIterable implements Iterable<string>{
  constructor(private strings:string[] = [], private currentIndex:number = 0){

  }
  [Symbol.iterator]():Iterator<string>{
    const that = this
    let currentIndex = that.currentIndex, length = that.strings.length

    const iterator:Iterator<string> = {
      next():{value : string, done : boolean}{
        const value = currentIndex  < length ? that.strings[currentIndex++] : undefined
        const done = value == undefined
        return {value, done}
      }
    }
    return iterator
  }
}

위 코드를 실행하면 StringIterable 클래스의 strings 속성에 담긴 배열의 아이템을 하나씩 출력한다.

import {StringIterable} from './stringIterable'
for(let value of new StringIterable(['helloe', 'world', '!']))
console.log(value)
profile
AllTimeDevelop

0개의 댓글