如何为仅获取属性赋值
Posted
技术标签:
【中文标题】如何为仅获取属性赋值【英文标题】:how to assign value to a get-only property 【发布时间】:2021-11-13 22:16:55 【问题描述】:正如电影结构如下所示,我想通过upVote
函数上传我的vote
保险库,但错误发生为“无法分配给属性:'vote' 是一个 get-only 属性”。
除了vote
和'isFavored,其他属性都是从本地JSON文件解码出来的。
我的结构
struct Movie:Codable,Identifiable
let id=UUID()
let MOVIE_ID:String
let NAME:String
let ALIAS:String
let ACTORS:String
let COVER:String
let DIRECTORS:String
let DOUBAN_SCORE:String
let DOUBAN_VOTES:String
let GENRES:String
let IMDB_ID:String
let LANGUAGES:String
let DIRECTOR_IDS:String
\\my own property:
var isFavered:Bool = false
\\init the vote
var vote:Int
if let v = Int(DOUBAN_VOTES)
return v
else
return 0
enum CodingKeys: String, CodingKey
case MOVIE_ID, NAME,ALIAS,ACTORS,COVER,DIRECTORS,DOUBAN_SCORE
case DOUBAN_VOTES,GENRES,IMDB_ID,LANGUAGES,MINS,OFFICIAL_SITE
case REGIONS,RELEASE_DATE,SLUG,STORYLINE,TAGS,YEAR,ACTOR_IDS,DIRECTOR_IDS
\\my uploade vote function
func upVote(newVote:Int)
vote = newVote \\ here occurs the error
【问题讨论】:
关于我在你之前的问题中的评论:现在你已经添加了 CodingKeys,没有理由再使用丑陋的 UPPER_SNAKE_CASE 属性名称???? 是的,谢谢我也从另一个答案中得到了同样的建议????一旦我弄清楚如何更改属性的值,我将更改它们 您的问题似乎得到了回答,但您的回答是把它变成一个完全不同的问题? 是的,实际上我是几周前开始使用 *** 的,在这种情况下,我应该提出一个新问题吗? 我已回滚问题以匹配最初提出的问题和已回答的问题。请改为发布新问题。 【参考方案1】:您首先需要将DOUBAN_VOTES
声明为可变,然后将计算属性更改为可变。通过将private(set)
用于 DOUBAN_VOTES,它将在结构之外是不可变的。
private(set) var DOUBAN_VOTES: String
var vote: Int
get
return Int(DOUBAN_VOTES) ?? 0
set
DOUBAN_VOTES = String(newValue)
【讨论】:
感谢您的回答!DOUBAN_VOTE
可以保持为let
吗?比如将newValue
传递给vote
而不是DOUBAN_VOTE
不,此解决方案必须是可变的。也许最好寻找一个完全不同的解决方案,例如为投票创建一个新的结构或类,以便 Movie 结构都是不可变的。
好的,我试试,再次感谢!!
嗨,我添加了一个myMovie
类,如问题中所示。但是在测试页面上,当我单击投票按钮时,值没有改变。【参考方案2】:
你有两个问题。
首先,正如您所发现的,您不能修改vote
,因为它是computed property。它的值由其 getter 方法中的代码确定。赋值没有意义。
我猜您使用了计算属性,因为坦率地说,您的 JSON 源很糟糕。整数应该作为整数发送,而不是字符串。
假设您无法将 JSON 更改为更合理的内容,那么您只需要更新 upVote
函数中的底层 DOUBAN_VOTES
属性即可。您需要将DOUBAN_VOTES
设为var
,而不是let
。
这将揭示您的第二个问题;结构是不可变的。为了允许函数更改值,必须将其标记为 mutating
函数。
var DOUBAN_VOTES:String
mutating func upVote(newVote: Int)
self.DOUBAN_VOTES = "\(newVote)"
【讨论】:
感谢您的回答!确实,我的 JSON 源很糟糕,我不确定是否适合将我的DOUBAN_VOTES
属性设置为 var,因为它是从文件中读取的。如果我更改数据,是否需要写回 JSON 文件?因为如果从文件中重新读取它的值不会改变。
将更新的数据写回服务器是完全不同的事情。是的,在典型的客户端/服务器应用程序中,您会将更改持久化回服务器。假设此时不在您的范围内,那么修改 DOUBAN_VOTES
属性没有问题,只需认识到您的更改不会被持久化,并且下次获取数据时它将是原始数据。此外,由于您已经麻烦添加了CodingKeys
,您应该使用它们来制作 Swift 样式的属性名称。
感谢您的建议,我已更改属性名称并添加了一个新类以使其他属性可更改,并在我的问题中更新。但是我不知道为什么单击投票按钮时无法更改值
值在哪里没有变化?在结构上?在屏幕上?如果您正在谈论更改屏幕上的值,则需要编写在更改值时更新屏幕的代码。它不会自动发生。你用的是 UIKit 还是 SwiftUI?
我从您的回滚编辑中看到您正在使用 SwiftUI,因此您需要考虑使用合适的模型;一个 ObservableObject,例如以上是关于如何为仅获取属性赋值的主要内容,如果未能解决你的问题,请参考以下文章
我如何为 Apollo Client 指定 GraphQL 查询并获取属性出现适当字符串的项目
如何为有条件的必需属性实现客户端验证 - Razor ASP.NET 核心