قالب وردپرس درنا توس
Home / IOS Development / Changes with associated values

Changes with associated values



Enums is a powerful tool that allows you to create expressive and accurate APIs. However, recovery of associated values ​​with a switch is sometimes a bit lumpy.

Consider the following example:

  enum Layout {
case view (width: CGF
case space (width: CGF
case newline
}

Here we model an UI layout: We can place either a view or a space on a line, both of which have an associated value for their width or break to a new line. If we want to calculate the total width of impressions and spaces under layout calculations, we can type something like this:

  change layout {
case la .view (width):
currentX + = width
case la. space (width):
currentX + = width
case .newline:
break
}

Alternatively, as long as the variables we are binding in the cases fit together, we can combine the issues and write this in a more consistent way:

  change the layout {
case la. fish (width), la. space (width):
currentX + = width
case .newline:
break
}

This will also work with nested enums. For example, we may support different types of widths in our layout, such as absolute widths and flexible widths:

  enum Width {
case absolute (CGFLOAT)
case flexible
}

Enum Layout {
case view
case space (width)
case newline
}

To calculate minimum width on a line, we will extract all absolute width values. We could accomplish this by writing an unclear change sentence, duplicate a lot of code:

  change layout {
case la .view (width):
change width {
case la .absolutt (x):
currentX + = x
case. flexible:
break
}
case la. space (width):
change width {
case la .absolutt (x):
currentX + = x
case. flexible:
break
}
case .newline:
break
}

Instead, we can express the same logic in a more elegant way:

  change layout {
case la .view (.absolute (x)), la .space (.absolute (x)):
currentX + = x
case .view (.flexible), .space (.flexible), .newline:
break
}

This technique can lead to unwanted complexity, especially where we need to describe many patterns in a single case . If we add a minimum width value for the .flexible case, we must already enter four different patterns:

  enum Width {
case absolute (CGFLOAT)
case flexible (minimum: CGF
}

change layout {
case la .view (.absolute (x)), la .view (.flexible (x)), la .space (.absolute (x)), la .space (.flexible (x)):
currentX + = x
case .newline:
break
}

We can reduce this complexity by using a calculated property to distinguish the match on Layout enum from the match on Width enum:

  extension Width {
was minimum: CGF
change yourself
case la .absolute (x), la .flexible (x): return x
}
}
}

change layout {
case la. fish (width), la. space (width):
currentX + = width.minimum
case .newline:
break
}

This example is inspired by an upcoming Swift Talk series, which builds an adaptive layout library. Our goal is to define layouts in a way that makes it easy to accept large variations in screen size, font size, and so on.

Here is a small preview:




Source link