Swift属性包装器创建报错及大写功能失效问题求助
Swift 属性包装器(Property Wrapper)问题修正:字符串大写功能失效
问题描述
学习Swift属性包装器时,官方示例代码运行正常,但自行实现的Capitalize属性包装器遇到以下问题:
- 未添加
init(wrappedValue:)初始化器时,出现「无法将String类型转换为Capitalize类型」的错误 - 添加初始化器后错误消失,但属性包装器无法实现字符串大写功能
官方示例代码
@propertyWrapper struct TwelveOrLess { private var number = 0 var wrappedValue: Int { get { return number } set { number = min(newValue, 12) } } } struct SmallRectangle { @TwelveOrLess var height: Int @TwelveOrLess var width: Int } var rectangle = SmallRectangle() print(rectangle.height) // Prints "0" rectangle.height = 10 print(rectangle.height) // Prints "10" rectangle.height = 24 print(rectangle.height) // Prints "12"
错误代码
@propertyWrapper struct Capitalize{ private var str1 = String() var wrappedValue: String{ get {return self.str1} set {self.str1 = str1.uppercased()} } init(wrappedValue: String){ self.str1 = wrappedValue } } struct test{ @Capitalize var testStr: String } var test1 = test(testStr: "dwa") print(test1.testStr)
问题分析
- 类型转换错误原因:Swift规定,若要在结构体初始化时直接传入原始类型值(如
test(testStr: "dwa")),属性包装器必须实现接收wrappedValue参数的初始化器,否则编译器无法自动将原始类型转换为包装器类型。 - 大写功能失效原因:
wrappedValue的setter中错误使用了旧值str1来转大写,而非新传入的newValue,导致赋值操作根本没有更新为新值的大写形式- 初始化器中仅直接保存了原始初始值,未对其做大写处理,导致初始值也不是大写状态
修正后的代码
@propertyWrapper struct Capitalize { private var str1: String var wrappedValue: String { get { str1 } set { str1 = newValue.uppercased() } } // 初始化时直接将传入值转为大写 init(wrappedValue: String) { self.str1 = wrappedValue.uppercased() } } struct Test { @Capitalize var testStr: String } // 测试初始值 var test1 = Test(testStr: "dwa") print(test1.testStr) // 输出 "DWA" // 测试赋值更新 test1.testStr = "hello" print(test1.testStr) // 输出 "HELLO"
修改要点
- 将
wrappedValue的setter逻辑改为使用newValue.uppercased(),确保新赋值的内容被转为大写后保存 - 初始化器中直接对传入的
wrappedValue执行大写转换,保证初始值就是大写状态 - 优化私有变量
str1的定义,去掉默认空字符串,改为在初始化时赋值,避免冗余
内容的提问来源于stack exchange,提问作者Fopoki
相关产品推荐
相关产品推荐

