I have an array of TemplateASTNode objects:
enum TemplateASTNode {
case blockNode(Block)
case sectionNode(Section)
case textNode(String)
// Define structs instead of long tuples
struct Block {
let innerTemplateAST: TemplateAST
let name: String
}
struct Section {
let tag: SectionTag
let expression: Expression
let inverted: Bool
}
// Factory methods
static func block(innerTemplateAST: TemplateAST, name: String) -> TemplateASTNode {
return .blockNode(Block(innerTemplateAST: innerTemplateAST, name: name))
}
static func section(templateAST: TemplateAST, expression: Expression, inverted: Bool, openingToken: TemplateToken, innerTemplateString: String) -> TemplateASTNode {
let tag = SectionTag(innerTemplateAST: templateAST, openingToken: openingToken, innerTemplateString: innerTemplateString)
return .sectionNode(Section(tag: tag, expression: expression, inverted: inverted))
}
static func text(text: String) -> TemplateASTNode {
return .textNode(text)
}
}
Objects are constructed with different factory methods — section
, text
, block
, but in debugger actual class is TemplateASTNode
.
- How to check actual type of
TemplateASTNode
instance — Section, Text, Block? - How exacly this mechanism works? Need a start point what to google.
Swift magic seems a bit confusing for me:
- we call factory method
section()
- it calls case
sectionNode
— I suppose it's a pointer to Enum attribute/choice - sectionNode holds a pointer to constructor Section which is a private structure inside TemplateASTNode
I expect a struct of type Section should be instantiated, but the generic TemplateASTNode one is produced. Why?
CodePudding user response:
Why TemplateASTNode is Created
So the functions are actually using a case
of the enum, this case
could be .textNode
but that case requires a string, which you give it.
So essentially the TemplateASTNode is acting as a wrapper to centralise all these models into one place, and your actual Structs are being held within the enum cases
Therefor you get given back a TemplateASTNode, which in this case could either be a .textNode
.blockNode
or .sectionNode
each containing their respective data.
How to distinguish between them
As we've just established, these are all cases
therefore we can use something called a switch
. To sum up what this does, it essentially allows you to give it an enum, then add logic depending on which case
it is. So for you, you'd want something like this:
switch templateASTNode { // These should be the variable and not the class
case .textNode(let text):
// Perform logic for text node
case .sectionNode(let section):
// Perform logic for section node
case .blockNode(let block):
// Perform logic for block node
}