Home » Development » Page 3

Development

프로그래밍 언어 및 환경

Opaque 리턴타입(Swift 5.1)

이 글을 다음 문서를 부분 번역한 것입니다.
https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html

Opaque 리턴 타입이 있는 함수나 메소드는 리턴 값에 대한 정보를 숨깁니다. 함수의 리턴 타입에 대한 구체적인 타입 정보를 제시하는 대신에, 리턴 값은 그 것이 따르는 프로토콜만으로 기술됩니다. 타입 정보를 숨기는 것은 모듈이 외부에 내놓는 코드에서 실제 리턴값의 타입은 내부에서만 유지관리될 수 있게 만들기 때문에 유용하게 사용될 수 있습니다. 리턴 값의 타입이 프로토콜 타입인 것과는 달리 Opaque 타입은 동일성을 유지합니다. 그리고 이때 컴파일러는 타입 정보에 액세스할 수 있지만, 모듈의 클라이언트는 그렇게 할 수 없습니다.

더 보기 »Opaque 리턴타입(Swift 5.1)

컨디션을 통한 스레드 동기화 예제

동시성을 다룰 때에는 특정한 자원을 동시에 액세스하지 못하도록 관리하거나 여러 작업들이 시작되는 시점을 맞추는 동기화 수단이 필요할 수 있다. Lock은 특정 코드 영역을 동시에 여러 스레드가 실행하지 못하도록 보호할 때 사용하며, 이벤트는 여러 스레드들이 특정 이벤트가 발생할 때까지 기다리다가 동시에 시작될 수 있도록 한다. 컨디션(Condition)은 락과 이벤트가 결합되어 있는 동기화 수단이다.

컨디션은 락을 내재하고 있는 이벤트라 할 수 있다. 락과 마찬가지로 acquire() ~ release() 구간이 있어 한 번에 하나의 스레드/프로세스가 실행되는 영역을 만들 수 있는데, 그 사이에 wait()를 통해서 이벤트를 기다릴 수 있다. 이때 한 스레드가 락을 잠근 상태에서 wait()를 호출하여 이벤트를 기다리게 되면, 같은 컨디션 객체를 점유하고자 하는 스레드가 다시 락을 얻어서 크리티컬 영역에 진입할 수 있다. 이와 같은 방식으로 여러 스레드가 크리티컬 영역에서 이벤트를 기다리는 상태가 될 때, 누군가가 해당 컨디션 이벤트를 set()하게 되면 대기 중인 모든 스레드가 깨어나게 된다. 하지만 이들은 모두 같은 크리티컬 영역에서 대기 중이었기 때문에 일반 이벤트와 달리 한꺼번에 동시에 시작하지 않고, 한 번에 하나씩 크리티컬 영역의 코드를 실행한다. 깨어난 스레드가 락을 릴리즈하는 시점에 wait()를 끝낸 다른 스레드가 실행되는 식으로 순차적으로 크리티컬 구간을 지나게 된다.

더 보기 »컨디션을 통한 스레드 동기화 예제

(Python) 리스트의 인덱스와 범위를 쉽게 이해하는 방법

리스트의 인덱스는 0부터 시작한다. 사실 많은 프로그래밍 언어에서 배열의 인덱스는 0부터 시작하기 때문에 “맨 첫원소가 0번이고 그 다음은 1번… N번째 원소는 N-1로 참조할 수 있다.”고 외워두면 그리 헷갈리지는 않는다.

그런데 이게 슬라이스 범위 문법에서는 또 헷갈린다. 그 이유는 슬라이스에서 뒤쪽 범위는 포함되지 않기 때문이다. 게다가 파이썬 리스트는 음수 인덱스를 사용해서 뒤에서부터 위치를 지정하는 것도 있다. 자, 첫번째 원소는 0번인데 뒤에서 부터 세면 -1 번부터 시작한다. 그렇다면 -5:-2는 어디서부터 어디까지일까?

더 보기 »(Python) 리스트의 인덱스와 범위를 쉽게 이해하는 방법

(Python) 그 날짜가 몇 주째인지 계산하기

특정한 년,월,일을 입력 받았을 때 그 날짜가 해당 월의 몇 째 주에 속하는지를 알려주는 함수를 작성해보자. 예를 들어 2020년 4월 27일 월요일은 4월의 5주차에 해당하는 날이다. 2020년 5월 15일은 2주차에 해당하는 날이다. 27, 15일은 각각 7로 나누는 것만으로도 3주나 차이가 나는데, 정확한 계산방법은 무엇일까?

더 보기 »(Python) 그 날짜가 몇 주째인지 계산하기

파이썬 미니포맷(format()) 사용법

우리는 값을 출력할 때 print() 함수를 사용한다. (python2에서 print는 구문이었지만, python3에서는 함수로 바뀌었다.) print() 함수는 전달 받은 인자를 문자열로 변환하여 표준 출력을 통해서 해당 문자열을 내보낸다. 만약 print(1)이라고 하면 정수 객체를 표현하는 문자열인 "1"을 생성하여 이것을 출력하는 것이다.

하지만 경우에 따라서는 출력되는 값이 이런 저런 양념을 넣어야 할 때가 있다. 고정된 폭에 맞추어 출력하거나 숫자값의 경우에는 세자리마다 콤마를 넣거나 소수점 자리수를 한정해야 할 때도 있다. 공학 계산의 결과를 출력할 때에는 유효숫자의 자리수 만큼 값을 표시하기 위한 서식을 적용해야 할 때도 있다.

더 보기 »파이썬 미니포맷(format()) 사용법

(Vim) Ex 프롬프트에서의 편집 방법

vim을 사용하다보면 입력모드 만큼이나 명령모드도 많이 쓰게 된다. 기본적으로 vim은 명령 입력 프롬프트에서도 탭 키만 누르면 다양한 자동완성을 이미 지원해주고 있다. 오늘은 Ex모드에서 알아두면 유용할 몇 가지 팁을 소개한다.

맵핑을 적용하기

cmap을 사용하면 Ex모드에서 명령줄을 편집할 때 사용될 키맵을 작성할 수 있다. 입력모드와 마찬가지로 jk를 눌러서 빠져나온다던지, 혹은 <expr> 키 맵을 사용해서 특정한 변수나 함수 실행 결과를 사용할 수도 있다.

:cnoremap jk <Esc>

하지만, Ex모드에서도 기본적인 커서이동, 삭제와 같은 편집 기능은 물론 자동완성도 제공해준다. 굳이 할 필요는 없을 듯… 또, 기본적으로 위/아래 화살표 키를 눌러서 이전 입력 히스토리를 탐색할 수 있다. (이전 입력 히스토리는 <C-F>를 눌러서 전체를 보면서 찾을 수도 있다.)

더 보기 »(Vim) Ex 프롬프트에서의 편집 방법

(Python) Awaitable에 대해

await 키워드를 통해서 실행이 완료되기 전에 다른 작업으로 전환이 가능한 동작을 모두 대기가능(awaitable)하다고 한다. 대기 가능한 객체 타입에는 코루틴(asycio.corutine), Task, Future가 있다.

코루틴

이 글에서 말하는 코루틴은 yield를 사용하는 전통적 의미의 코루틴이 아닌 asycio 라이브러리 내에 정의된 비동기 코루틴을 의미하며, 이는 async def 키워드를 사용하여 정의한 함수(코루틴 함수)가 리턴하는 객체이다. 아래 예제에서 #1의 코드는 실질적으로 아무일도 하지 않는데, nested()를 실행만 하면 코루틴 객체를 생성만 하고 실행(스케줄링)을 하지 않기 때문이다.

더 보기 »(Python) Awaitable에 대해

Decimal – 보다 정확한 소수점 산술

들어가기 전에 다음과 같은 코드를 보자. 흔히 하는 실수 중에 하나 인데 float 타입 값으로 반복횟수가 제한된 루프를 만드려고 시도하는 것이다.

a, b = 1, 0.1
while a != 0:
  print(a)
  a -= b

하지만 안타깝게도 이 코드는 의도대로 실행되지 않을 것이다. 왜냐하면 1.0 에서 0.1을 열 번 뺀다하더라도 0이 되지 않기 때문이다. 어째서? (실제로 파이썬 쉘에서 1.0 / 10 == 0.1 이고, 0.1 * 10 == 1 이다)

더 보기 »Decimal – 보다 정확한 소수점 산술

Swift 프로퍼티의 옵저버에 대한 규칙

lazy 프로퍼티는 옵저버를 가질 수 없다. (단 최초 액세스 이후 변경하는 것은 가능하다.) computed 프로퍼티에 대해서는 옵저버를 설치하는 것이 의미가 없다. 단 상속받은 computed 프로퍼티에 대해서는 옵저버를 설치할 수 있다. 옵저버는 해당 클래스의 지정 이니셜라이저 내에서 값을 변경하는 경우에는 호출되지 않는다. 단, 상속받은 프로퍼티가 옵저버가 설치되어 있다면 부모의 지정 이니셜라이저 호출 후에 변경한다면, 부모의 옵저버가 호출될 것이다. 비슷하게 편의 이니셜라이저에서는 지정 이니셜라이저를 통해 초기화한 후, 프로퍼티값을 다시 변경하면 옵저버가 실행된다. lazy 프로퍼티와 옵저버 lazy 프로퍼티는 옵저버를 가질 수 없다. 위에서… 더 보기 »Swift 프로퍼티의 옵저버에 대한 규칙

코코아바인딩에서 집합 타입의 프로퍼티를 연결할 때 유의할 점

코코아 바인딩을 사용할 때 특정한 키 이름이 변경가능한 배열(NSMutableArray)일 때, UI를 통해 값을 추가/제거하거나 변경한다 하더라도 이러한 변경이 원래 데이터에 반영되지 않는 문제가 발생하는 경우가 있다.

원문 : 코코아 바인딩 문제해결(Troubleshooting Cocoa Bindings)
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CocoaBindings/Concepts/Troubleshooting.html

집합 컨트롤러가 현재 데이터를 표시하지 않아요.

“이러한 문제는 보통 여러분의 애플리케이션이 집합 콘텐츠를 키-밸류 옵저빙 호환 방식으로 데이터를 변경하지 않기 때문에 일어납니다. 배열을 addObject:removeObject: 로 제거하는 것만으로는 부족합니다.”

더 보기 »코코아바인딩에서 집합 타입의 프로퍼티를 연결할 때 유의할 점