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

如何在Swift的Color扩展中避免重复计算components?

问题描述

我编写了如下的SwiftUI Color扩展:

extension Color {
    
    var cgColor: CGColor {
        resolve(in: .init()).cgColor
    }
    
    var r: Int {
        guard let components = cgColor.components, components.count == 4 else {
            return 0
        }
        return Int(components[0] * 256)
    }
    
    var g: Int {
        guard let components = cgColor.components, components.count == 4 else {
            return 0
        }
        return Int(components[1] * 256)
    }
    
    var b: Int {
        guard let components = cgColor.components, components.count == 4 else {
            return 0
        }
        return Int(components[2] * 256)
    }
    
    var a: Double {
        guard let components = cgColor.components, components.count == 4 else {
            return 1
        }
        return components[3]
    }
    
}

目前r、g、b、a属性中都会重复获取并校验cgColor.components,请问如何在扩展内部避免这部分重复计算?我曾在使用该颜色的地方存储变量,但希望能在扩展内实现。


解决方案

可以通过提取私有计算属性来复用components的校验逻辑,将重复代码集中到一处,同时保持r/g/b/a属性的简洁性:

extension Color {
    var cgColor: CGColor {
        resolve(in: .init()).cgColor
    }
    
    // 私有计算属性,集中处理components的获取与校验
    private var rgbaComponents: (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat)? {
        guard let components = cgColor.components, components.count == 4 else {
            return nil
        }
        return (components[0], components[1], components[2], components[3])
    }
    
    var r: Int {
        guard let components = rgbaComponents else {
            return 0
        }
        return Int(components.r * 256)
    }
    
    var g: Int {
        guard let components = rgbaComponents else {
            return 0
        }
        return Int(components.g * 256)
    }
    
    var b: Int {
        guard let components = rgbaComponents else {
            return 0
        }
        return Int(components.b * 256)
    }
    
    var a: Double {
        guard let components = rgbaComponents else {
            return 1
        }
        return Double(components.a)
    }
}

优化说明

  1. 新增的rgbaComponents私有属性承担了所有重复的逻辑:获取cgColor.components、校验组件数量是否为4,最终返回一个包含RGBA值的可选元组。
  2. r/g/b/a属性只需判断rgbaComponents是否存在,直接从元组中取值计算即可,彻底消除了重复代码。
  3. 这种方式既保持了扩展的内聚性,又提升了代码的可维护性——后续如果需要调整校验逻辑,只需修改rgbaComponents一处即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 16:13:13