# 代码注释规范

## 基本原则

1. 注释应该解释为什么（Why），而不是是什么（What）
2. 代码即文档，优先通过良好的命名和结构来表达意图
3. 注释要及时更新，过时的注释比没有注释更糟糕
4. 避免无意义的注释，如果代码足够清晰就不需要注释

## 注释类型

### 1. 文件头注释
```typescript
/**
 * @fileoverview 文件的用途描述
 * 
 * 详细说明（可选）
 * 
 * @author 作者名 <邮箱>
 * @copyright InnoTech
 * @license UNLICENSED
 */
```

### 2. 类注释
```typescript
/**
 * 类的用途说明
 * 
 * @class
 * @implements {Interface}
 * @extends {ParentClass}
 */
```

### 3. 方法注释
```typescript
/**
 * 方法功能说明
 * 
 * @param {string} param - 参数说明
 * @returns {boolean} 返回值说明
 * @throws {Error} 异常说明
 * @private
 */
```

### 4. 行内注释
```typescript
// 复杂逻辑的简要说明
const result = complexCalculation();

/* 多行注释
 * 用于较长的说明
 * 通常用于算法解释
 */
```

## 注释规范

### 1. 必须注释的场景
- 所有导出的类、接口、类型、函数
- 复杂的算法或业务逻辑
- 特殊的边界条件处理
- Hack和临时解决方案
- 依赖外部系统的代码

### 2. 不应注释的场景
- 显而易见的代码
- 已经通过变量名表达的含义
- 简单的赋值和操作
- 重复代码的含义

### 3. 注释格式
- 使用完整的句子
- 句尾使用句号
- 保持适当的缩进
- 注释和代码之间留一个空格

## 特殊注释标记

### 1. TODO 注释
```typescript
// TODO(开发者): 需要完成的工作
// TODO(#123): 关联issue的工作
```

### 2. FIXME 注释
```typescript
// FIXME: 已知问题的说明
// FIXME(#456): 关联issue的问题
```

### 3. HACK 注释
```typescript
// HACK: 特殊处理的说明
// HACK: 后续需要优化
```

## 示例

### 1. 业务逻辑注释
```typescript
/**
 * 计算订单总价
 * 
 * 计算规则：
 * 1. 商品原价总和
 * 2. 减去折扣金额
 * 3. 加上运费
 * 4. 抹去小数部分
 */
function calculateOrderTotal(items: OrderItem[], discount: number, shipping: number): number {
  // 计算商品总价
  const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);

  // 应用折扣（如果有）
  const discounted = discount > 0 ? subtotal * (1 - discount) : subtotal;

  // 添加运费并取整
  return Math.floor(discounted + shipping);
}
```

### 2. 算法注释
```typescript
/**
 * 二分查找实现
 * 
 * 时间复杂度: O(log n)
 * 空间复杂度: O(1)
 */
function binarySearch<T>(arr: T[], target: T): number {
  let left = 0;
  let right = arr.length - 1;

  while (left <= right) {
    // 避免整数溢出的中点计算
    const mid = left + Math.floor((right - left) / 2);

    if (arr[mid] === target) {
      return mid;
    } else if (arr[mid] < target) {
      left = mid + 1;  // 在右半部分查找
    } else {
      right = mid - 1;  // 在左半部分查找
    }
  }

  return -1;  // 未找到目标值
}
``` 