'Trying to change a variable set as var, but can't change it within the structure it exists
Working on the upload section of my app, after uploading a file from the iPhone, the server puts the file through multiple processing stages.
I use a struct that keeps the uploaded file info, scripts to call, etc.
struct XFile {
let key: String
let filename: String
let data: Data
var mimeType: String?
let url: URL
var toUrl : URL?
var upStatus : UpStatus?
var fileStage : Int32?
init(fileUrl: URL, key: String) {
//setting multiplle variables here
//set the initial fileStage to 0
self.fileStage = 0
}
}
I declare and create my XFile structure from within my UIViewControler with:
class UploadFile : UIViewController, URLSessionDelegate {
var xFile : XFile?
//buttonAction
xFile = XFile(fileUrl: url, key: "filename")
}
When I attempt to change xFile.fileStage from within XFile itself, or within the UIViewControler that created that instance of XFile, I have no problems.
However, if I pass xFile as a parameter into a different class's function, I cannot change the variable xfile.fileStage without getting the following compiler editor:
Cannot assign to property: 'xFile' is a 'let' constant
However, I do not get the error if I send xFile as a reference to xFile to that 3rd class.
getService.start(upFile: &xFile!, upLoadInvoiceClass: self)
Is this normal behavior?
Is it that passing xFile in a function sends a copy?
I just want to make sure I am understanding AND using it properly.
Solution 1:[1]
This is because you are using struct not class. Struct makes a copy of itself when you pass it through the functions.
There are two solutions:
Either change the struct to class.
Make a mutating method in struct which can change the fileStage
struct XFile { let key: String let filename: String let data: Data var mimeType: String? let url: URL var toUrl : URL? var upStatus : UpStatus? var fileStage : Int32?
init(fileUrl: URL, key: String) { //setting multiplle variables here //set the initial fileStage to 0 self.fileStage = 0 } mutating func updateFileStage(_ stage: Int32) { self.fileStage = stage }
}
Solution 2:[2]
Is this normal behavior?
Yes, because all parameters passed into a swift function are constants. You can't change them. If you want then pass the parameter as inout
. Here is an example.
func doubleInPlace(number: inout Int) {
number *= 2
}
var myNum = 10
doubleInPlace(number: &myNum)
print(myNum) // value is 20
Is it that passing xFile in a function sends a copy?
Yes, because struct
instances are value types. It will send a copy when passed as a parameter in a function. You can check this.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Ghulam Mustafa |
Solution 2 | MBT |