c24165b8bc
에이전트 8종(대화형/프로그래머 C·S/디자이너/설계자/기획자/QA/PD/PM)에게 [공통 기본 능력 + 롤별 Specialty] 2층으로 지식을 주입하기 위한 재분류. 문서 내용·포맷은 무수정, 폴더 이동만 (6,372개 문서 수 보존 확인). - Topic_Programming → Domain_Programming (내부 구조 보존) - Topic_Graphic → Domain_Design - Topic_Business → Domain_Product - Topic_General → Domain_General - _Common 신설: Math(구 Topic_Math_Specialty), Reasoning(구 General/From_Thinking & Reasoning), Reasoning_Creativity(구 General/From_창의성), Communication(Poetic_Blog_Writing + From_writing) - 타 도메인의 From_* 폴더는 유지 (출처 표기일 뿐, 이미 도메인에 맞게 분류된 문서) - 빈 폴더 정리 (memory/procedures) - 에이전트→폴더 매핑은 workspace의 .astra/agent-knowledge-map.json (9개 에이전트) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5.3 KiB
5.3 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, created_at, updated_at, last_reinforced, review_reason, merge_history, tags, raw_sources, tech_stack, applied_in
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | created_at | updated_at | last_reinforced | review_reason | merge_history | tags | raw_sources | tech_stack | applied_in | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| null-safety-patterns | Null 안전 패턴 (Null Safety Patterns) | Coding | draft | null-safety-patterns |
|
null | B | 0.85 | conceptual | 2026-05-09 | 2026-05-09 | 2026-05-09 |
|
|
|
Null 안전 패턴
Null/undefined 는 "값이 없음"이라는 정보를 담지 못하는 가장 빈약한 표현. 타입에서 nullable 을 명시적으로 분리하고, 언래핑 지점을 명확히 만들어라.
📖 핵심 개념
Tony Hoare가 "the billion dollar mistake" 라고 부른 null 참조 문제. 모던 언어들은 다음 중 하나로 대응:
- 타입 시스템에서 nullable 분리: TypeScript
T | null, KotlinT?, SwiftT? - Optional 타입: Rust
Option<T>, HaskellMaybe a - Strict mode: TS의
strictNullChecks, Kotlin 디폴트, Swift 디폴트
핵심은 "이 값은 없을 수 있다"를 타입이 명시적으로 표현하고 컴파일러가 강제하는 것.
💻 코드 패턴
1. nullable 명시 (TypeScript with strictNullChecks)
// ❌ 모호함 — name 이 항상 있는지 가끔 없는지 모름
function greet(user: { name: string }) { return `Hi, ${user.name}`; }
// ✅ 명시
function greet(user: { name: string | null }) {
if (user.name === null) return 'Hi, friend';
return `Hi, ${user.name}`;
}
2. Optional Chaining + Nullish Coalescing
// 깊은 경로 안전 접근
const city = order?.shipping?.address?.city ?? 'Unknown';
// ❌ 주의: || 는 falsy("" / 0) 도 fallback 으로 처리
const port = config.port || 3000; // port가 0이면 3000 됨!
const port = config.port ?? 3000; // null/undefined 만 fallback ✓
3. 타입 가드 + 좁히기
function isPresent<T>(x: T | null | undefined): x is T {
return x !== null && x !== undefined;
}
const items = users.map(u => u.email).filter(isPresent); // string[]
4. Maybe / Option 모나드 패턴 (TS)
type Some<T> = { kind: 'some'; value: T };
type None = { kind: 'none' };
type Maybe<T> = Some<T> | None;
const some = <T>(value: T): Maybe<T> => ({ kind: 'some', value });
const none = (): Maybe<never> => ({ kind: 'none' });
function map<T, U>(m: Maybe<T>, f: (t: T) => U): Maybe<U> {
return m.kind === 'none' ? m : some(f(m.value));
}
function getOr<T>(m: Maybe<T>, fallback: T): T {
return m.kind === 'some' ? m.value : fallback;
}
복잡한 변환 체인이 많을 때만 도입. 단순한 T | null 로 충분한 경우엔 over-engineering.
5. Non-null assertion (!) 의 좁은 사용
const el = document.getElementById('root')!; // OK if you control the HTML
// ❌ 위험
function findUser(id: string) {
return users.find(u => u.id === id)!; // 못 찾으면 런타임 사고
}
// ✅
function findUser(id: string): User {
const u = users.find(u => u.id === id);
if (!u) throw new NotFoundError(id);
return u;
}
🤔 의사결정 기준
| 시그니처 | 의미 | 사용 시점 |
|---|---|---|
T |
항상 값 있음 | 강한 보장이 필요할 때 (도메인 invariant) |
T | null |
값이 의도적으로 없을 수 있음 | "선택 사항" 의미 명확할 때 |
T | undefined |
아직 초기화 안 됨 / 키 없음 | object property optional 표현 |
T | null | undefined |
둘 다 가능 | 외부 데이터 (API 응답) — 즉시 정규화 권장 |
Maybe<T> / Option<T> |
변환 체이닝이 잦음 | 복잡한 nullable pipeline |
❌ 안티패턴
any로 회피: 타입 시스템 우회. 컴파일은 통과하지만 런타임 폭사.- Non-null assertion 남발 (
x!.y!.z!): 컴파일러를 침묵시키지만 보장 없음. 매번 가드 또는 스키마 검증. ||로 falsy 까지 fallback: 0, "", false 가 의미 있는 값일 때 사고.??사용.- null 과 undefined 둘 다 보내기: 한 코드베이스에서 한 컨벤션 (보통
undefined권장 — JSON 직렬화 시 사라져 명시적). - null check 잊고 nested access:
obj.a.b.c가obj.anull 일 때 폭사. optional chaining?.사용. - 외부 API 응답을 그대로 nullable 채로 도메인 깊숙이 전파: 경계에서 zod / io-ts 같은 스키마로 정규화.
🤖 LLM 활용 힌트
- LLM에게 함수 작성: "strictNullChecks 가정. 가능한 nullable 은 시그니처에 명시" 라고 요청.
- 외부 API 파싱: "zod 같은 라이브러리로 nullable 을 즉시 도메인 타입으로 정규화" 명시.
- TypeScript 옵션: 프로젝트
tsconfig.json에"strict": true또는 최소"strictNullChecks": true가 있어야 이 모든 패턴이 의미 있음.
🧪 검증 상태
- verification_status:
conceptual - Kotlin / Swift / Rust 의 default null safety 모델, TypeScript strictNullChecks 가 표준.
- 적용 사례 발견 시
applied_in추가.