You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift占星应用自定义整型格式化:位置数值循环进位实现需求

实现方案

要不要创建自定义类型

非常建议封装为独立自定义类型。原生Int类型不具备你需要的范围自动校验、循环转换、进位逻辑,封装后可以保证所有Position实例的取值永远符合业务规则,不需要上层业务重复写校验逻辑,大幅降低出错概率。

核心实现思路

  1. 内部用0基数值存储,简化模运算逻辑,对外暴露的属性按需转换为业务要求的1基(星座1~12)即可
  2. 统一封装归一化方法,所有属性修改、数值运算后统一调用,一次性处理进位、范围循环逻辑
  3. 遵守CustomStringConvertible协议实现自定义格式化输出

代码实现

struct Position {
    // 内部0基存储 简化模运算
    private var _sign: Int
    private var _degrees: Int
    private var _minutes: Int
    
    // 对外暴露的业务属性 符合占星规则
    var sign: Int {
        get { _sign + 1 }
        set { 
            _sign = newValue - 1
            normalize()
        }
    }
    var degrees: Int {
        get { _degrees }
        set { 
            _degrees = newValue
            normalize()
        }
    }
    var minutes: Int {
        get { _minutes }
        set { 
            _minutes = newValue
            normalize()
        }
    }
    
    init(sign: Int, degrees: Int, minutes: Int) {
        _sign = sign - 1
        _degrees = degrees
        _minutes = minutes
        normalize()
    }
    
    // 统一处理进位、范围循环逻辑 同时支持正负值处理
    private mutating func normalize() {
        // 处理分钟进位
        var minutesCarry = _minutes / 60
        _minutes = _minutes % 60
        if _minutes < 0 {
            _minutes += 60
            minutesCarry -= 1
        }
        
        // 处理度数进位
        _degrees += minutesCarry
        var degreesCarry = _degrees / 30
        _degrees = _degrees % 30
        if _degrees < 0 {
            _degrees += 30
            degreesCarry -= 1
        }
        
        // 处理星座循环
        _sign += degreesCarry
        _sign = _sign % 12
        if _sign < 0 {
            _sign += 12
        }
    }
    
    // 快捷加减方法 可按需扩展
    mutating func add(minutes: Int) {
        _minutes += minutes
        normalize()
    }
    
    mutating func add(degrees: Int) {
        _degrees += degrees
        normalize()
    }
}

// 格式化输出实现
extension Position: CustomStringConvertible {
    var description: String {
        "\(sign) \(degrees)’ \(minutes)\""
    }
}

效果验证

  • 非法值自动转换:Position(sign: 13, degrees: 30, minutes: 60) 输出为 2 1’ 0",符合循环规则
  • 进位逻辑验证:var pos = Position(sign: 12, degrees: 29, minutes: 59); pos.add(minutes: 1) 输出为 1 0’ 0",符合进位要求(如果需要展示为0 0 0,只需将sign的getter改为返回_sign即可)

可选优化

如果需要更强的取值控制,可以将sign/degrees/minutes的setter私有化,只开放add系列方法修改数值,完全避免上层直接赋值错误值。也可以重载+/+=等运算符,让数值运算的用法和原生类型保持一致。

内容的提问来源于stack exchange,提问作者bennetts_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:36:01