Swift字符串属性包装器编写报错:String无count和dropLast成员
问题原因及解决方案
你的错误根源在于泛型参数名冲突:
你把结构体声明为LessThanSixteen<String>,这里的<String>是将String作为泛型占位符使用,而非Swift原生的String类型。在结构体内部,所有的String指代的都是这个泛型占位符,它没有count、dropLast这些原生字符串的方法,因此编译报错。
而你在结构体外部的代码中,String是Swift原生类型,自然支持这些方法,所以不会出错。
修正方案
方案1:仅针对String类型(最贴合你的需求)
去掉泛型声明,直接使用原生String类型,同时注意dropLast返回的是Substring,需要转成String:
@propertyWrapper struct LessThanSixteen { var value: String var wrappedValue: String { get { value } set { // 赋值时也添加截断逻辑,保证值始终符合要求 value = newValue.count < 16 ? newValue : String(newValue.dropLast(newValue.count - 16)) } } init(wrappedValue: String) { self.value = wrappedValue.count < 16 ? wrappedValue : String(wrappedValue.dropLast(wrappedValue.count - 16)) } }
方案2:支持多种可截断类型(泛型版本)
如果需要让包装器支持其他集合类型(比如Array),可以使用泛型,但要避免用系统类型名作为泛型参数,同时添加必要的协议约束:
@propertyWrapper struct LessThanSixteen<T: RangeReplaceableCollection> where T: Collection { var value: T var wrappedValue: T { get { value } set { value = newValue.count < 16 ? newValue : newValue.dropLast(newValue.count - 16) as! T } } init(wrappedValue: T) { self.value = wrappedValue.count < 16 ? wrappedValue : wrappedValue.dropLast(wrappedValue.count - 16) as! T } }
内容的提问来源于stack exchange,提问作者Cory Steers
相关产品推荐
相关产品推荐

