Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing var tuple to Enum value

Tags:

ios

swift

Passing variable based tuple directly to enum with Tuple based values results in compilation error. For example:

I have an enum as below:

enum AnswerType  {
    case Objective(Int)
    case Subjective(question: Int, answer: String)
}

var stAnswer = (question: 1, answer: "Student's Answer")

let answerType = AnswerType.Subjective(stAnswer) //Compilation error here - "Missing argument for parameter answer in call"

This gives compiler error with Swift 2.1. But when I change stAnswer to constant using let it works fine. Anyone having idea whats causing the compiler error here?

like image 509
Evol Gate Avatar asked Oct 30 '15 06:10

Evol Gate


2 Answers

Swift cannot handle passing a var this way. It can only pass a constant tuple to initialize associated data. This is most likely just an unimplemented feature in the compiler, and I recommend opening a radar (bugreport.apple.com).

The easiest solution is to just declare the tuple as a constant:

let stAnswer = (question: 1, answer: "Student's Answer")
let answerType = AnswerType.Subjective(stAnswer)

If that isn't practical, then make a constant copy before you pass it (which is what the compiler should be able to do automatically).

var stAnswer = (question: 1, answer: "Student's Answer")
let values = stAnswer
let answerType = AnswerType.Subjective(values)

You could also get fancy and use a closure to force a copy. This feels a bit over-tricky to me, but some may prefer it:

let answerType = AnswerType.Subjective({stAnswer}())

You can also use @Rob's solution from the comments (copied here for future readers), which is fine IMO:

let answerType = AnswerType.Subjective(question: stAnswer.question, answer: stAnswer.answer)
like image 61
Rob Napier Avatar answered Sep 29 '22 21:09

Rob Napier


A typealias doesn't suffer from this curious behavior:

typealias SubjectiveType = (question: Int, answer: String)

enum AnswerType  {
    case Objective(Int)
    case Subjective(SubjectiveType)
}

var stAnswer = SubjectiveType(question: 1, answer: "Student's Answer")
stAnswer.answer = "Student's revised answer"

let answerType = AnswerType.Subjective(stAnswer)

Or you can use struct for SubjectiveType, too, and accomplish something very similar.

like image 38
Rob Avatar answered Sep 29 '22 21:09

Rob