Xcode 警告:不可变属性将不会被解码,因为它是用无法覆盖的初始值声明的 [英] Xcode warning: Immutable property will not be decoded because it is declared with an initial value which cannot be overwritten

查看:23
本文介绍了Xcode 警告:不可变属性将不会被解码,因为它是用无法覆盖的初始值声明的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

运行 Xcode 12,我的 Swift 5 Xcode 项目现在在 DecodableCodable 类型声明一个带有初始值的 let 常量时出现警告.

struct ExampleItem:可解码{let number: Int = 42//警告}

<块引用>

不可变属性不会被解码,因为它被声明为一个不能被覆盖的初始值

Xcode 建议将 let 更改为 var:

<块引用>

修复:改为使属性可变

 var number: Int = 42

它还建议修复:

<块引用>

修复:通过初始化程序设置初始值或明确定义一个 CodingKeys 枚举,包括一个标题"案例以消除此警告

这个新警告的目的是什么?应该注意还是忽略?这种类型的警告可以静音吗?

应该实施 Xcode 的修复吗?或者有更好的解决方案吗?

解决方案

Noah 的解释是正确的.这是错误的常见来源,由于 Codable 综合的神奇"行为,发生的事情并不是很明显,这就是为什么我 向编译器添加了此警告,因为它让您注意到属性不会被解码的事实,并且如果这是预期的行为,您会显式调用它.

正如修复程序所解释的那样,如果您想消除此警告,您有多种选择 - 您选择哪一个取决于您想要的确切行为:


  1. 通过 init 传递初始值:

struct ExampleItem: Decodable {让号:Int初始化(数字:Int = 42){self.number = 数字}}

这将允许对 number 进行解码,但您也可以传递使用默认值的 ExampleItem 实例.

你也可以直接在 init 中使用它,在解码过程中:

struct ExampleItem:可解码{让号:Int私有枚举 CodingKeys:字符串,CodingKey {案件编号}init(来自解码器:解码器)抛出{让容器 = 尝试decoder.container(keyedBy: CodingKeys.self)number = try container.decodeIfPresent(Int.self, forKey: .number) ??42}}

这将允许对 number 进行解码,但如果解码失败,则使用 42 作为默认值.


  1. 将属性设为 var,尽管您也可以将其设为 private(set) var:

struct ExampleItem: Decodable {变量编号:Int = 42}

使它成为 var 将允许对 number 进行解码,但它也允许调用者修改它.通过将其标记为 private(set) var,您可以根据需要禁止这样做.


  1. 定义一个显式的 CodingKeys 枚举:

struct ExampleItem: Decodable {让数:Int = 42私有枚举 CodingKeys:CodingKey {}}

这将防止 number 被解码.由于枚举没有大小写,这让编译器清楚地知道没有要解码的属性.

Running Xcode 12, my Swift 5 Xcode project now has warnings whenever a Decodable or Codable type declares a let constant with an initial value.

struct ExampleItem: Decodable {
    let number: Int = 42 // warning
}

Immutable property will not be decoded because it is declared with an initial value which cannot be overwritten

Xcode suggests changing the let to a var:

Fix: Make the property mutable instead

    var number: Int = 42

It also suggests the fix:

Fix: Set the initial value via the initializer or explicitly define a CodingKeys enum including a 'title' case to silence this warning

What is the purpose of this new warning? Should it be heeded, or ignored? Can this type of warning be silenced?

Should Xcode's fix be implemented? Or is there a better solution?

解决方案

Noah's explanation is correct. It’s a common source of bugs and it's not immediately obvious what’s happening due to the "magical" behaviour of Codable synthesis, which is why I added this warning to the compiler, since it brings your attention to the fact that the property won't be decoded and makes you explicitly call it out if that's the expected behaviour.

As the fix-it explains, you have a couple of options if you want to silence this warning - which one you choose depends on the exact behaviour you want:


  1. Pass the initial value via an init:

struct ExampleItem: Decodable {
  let number: Int
    
  init(number: Int = 42) {
    self.number = number
  }
}

This will allow number to be decoded, but you can also pass around instances of ExampleItem where the default value is used.

You can also use it directly inside init instead, during decoding:

struct ExampleItem: Decodable {
  let number: Int
    
  private enum CodingKeys: String, CodingKey {
    case number
  }
    
  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    number = try container.decodeIfPresent(Int.self, forKey: .number) ?? 42
  }
}

This will allow number to be decoded, but use 42 as the default value if the decoding fails.


  1. Make the property a var, although you can also make it a private(set) var:

struct ExampleItem: Decodable {
  var number: Int = 42
}

Making it a var will allow number to be decoded, but it will also allow callers to modify it. By marking it as private(set) var instead, you can disallow this if you want.


  1. Define an explicit CodingKeys enum:

struct ExampleItem: Decodable {
  let number: Int = 42
  
  private enum CodingKeys: CodingKey {}
}

This will prevent number from being decoded. Since the enum has no cases, this makes it clear to the compiler that there are no properties that you want to decode.

这篇关于Xcode 警告:不可变属性将不会被解码,因为它是用无法覆盖的初始值声明的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆