R.plurals는 단순한 if문이 아니다

안드로이드 리소스 중 plurals는 단어의 단수복수형을 처리해주는 리소스 타입입니다.

활용할 수 있는 대표적인 예가 1 friend, 2 friends가 있지요.

리소스는 아래와 같이 작성합니다.

    <plurals name="profile_label_friendsCount">
        <item quantity="one">%d friend</item>
        <item quantity="other">%d friends</item>
    </plurals>

이 리소스를 활용할 자바코드는 아래와 같겠죠.

    if (friendCount > 0)
        message = getResources().getQuantityString(R.plurals.profile_label_friendsCount, friendCount, friendCount);
    textViewFriendCount.setText(message);

지원되는 quantity는 총 6개입니다 (zero, one, two, few, many, other).
여기까지만 보면, “아! 그럼 0일 때 no friend라고 나오게 하려면 아래처럼 하면 되겠군”이라고 생각합니다.

    <plurals name="profile_label_friendsCount">
        <item quantity="zero">no friend</item> <!-- 추가 -->
        <item quantity="one">%d friend</item>
        <item quantity="other">%d friends</item>
    </plurals>

하지만 en-US 기준으로 “no friend”가 아닌 “0 friends”라고 나오는걸 알 수 있습니다.

하지만 이것은 버그가 아니랍니다 (code.google.com issue링크). 애초에 그렇게 만들어졌다는거죠. plurals라는 리소스 처리는, 언어마다의 숫자에 대한 표현이 문법적으로 다를 경우만 처리하는 것이지 if문의 대용으로 사용되는게 아닌거죠. 이는 API문서에도 주의를 주고 있습니다.

In English, a string for zero will be ignored even if the quantity is 0, because 0 isn’t grammatically different from 2, or any other number except 1 (“zero books”, “one book”, “two books”, and so on). Conversely, in Korean only the other string will ever be used.

위에 글을 읽어보면 영어는 one만 다르게 판단된다는군요. 한국어는 other만 취급되고요.

한편으론, 이건 무슨 기준으로 이런걸까요? StackOverflow의 한 답변에 의하면 이는 Unicode Common Locale Data Repository (일명 CLDR)라는 체계를 따르는 겁니다. 논리의 개념이 아닌 인간의 언어에 대한 개념으로 만들어진 것이지요. 이것은 오픈소스로 운영되고 있으며 근래 모던한 소프트웨어는 이 체계를 많이 따르고 있습니다.

어쨌거나 결론은, “No Friend”처리를 해야 할 때 우리는 아래처럼 평범한 if 문으로 처리해야 합니다.

    if (friendCount > 0)
        message = getResources().getQuantityString(R.plurals.profile_label_friendsCount, friendCount, friendCount);
    else // 친구 없을 때
        message = getString(R.string.profile_label_noFriend); // "no friend" string 표시
    textViewFriendCount.setText(message);

댓글 남기기