Tout en étudiant Swift par vous-même, vous utiliserez le résultat pour étoffer les connaissances que vous avez apprises. C'est la première fois que vous sortez, et cela sert également de pratique de sortie.
Apprenez en remodelant une classe de carrés avec une longueur Int de chaque côté.
Pouvoir utiliser les connaissances acquises en les codant sous une forme proche de la pratique.
-À propos de l'utilité de ** willSet ** et ** didSet ** --Utilisation de ** Propriété en lecture seule ** à l'aide des propriétés de calcul --Résolution des violations du principe DRY
--Dispose de propriétés de hauteur et de largeur de type Int
class IntBox{
enum Size{
case S, M, L
}
//Hauteur horizontale et verticale
var width: Int
var height: Int
var depth: Int
//le volume
var volume: Int
//Taille
var size:Size
init(w: Int, h: Int, d: Int){
//Initialisation de la hauteur horizontale et verticale
width = w
height = h
depth = d
//Initialisation du volume
volume = w * h * d
//Initialisation de la taille
switch volume{
case 1...8:
size = .S
case 9...64:
size = .M
default:
size = .L
}
}
//Une fonction pour afficher la liste des statuts est fournie pour vérification.
func printStatus(){
var status = """
---statut---
width: \(width)
height: \(height)
depth: \(depth)
volume: \(volume)
size: \(size)
"""
print(status)
}
}
let cb = IntBox(w: 1, h: 1, d: 1)
cb.printStatus()
//Essayez de changer la largeur
cb.width = 11
cb.printStatus()
//Essayez de changer le volume
cb.volume = -20
cb.printStatus()
//Essayez de changer la taille
cb.size = .L
cb.printStatus()
Résultat d'exécution
---statut---
width: 1
height: 1
depth: 1
volume: 1
size: S
---statut---
width: 11
height: 1
depth: 1
volume: 1 #Devraient changer!!
size: S
---statut---
width: 11
height: 1
depth: 1
volume: -20 #Il est étrange que 0 ou moins ne puisse pas être défini(Le volume dépend de la longueur de chaque côté)
size: S
---statut---
width: 11
height: 1
depth: 1
volume: -20
size: L #Il est étrange qu'il puisse être réglé ainsi que le volume. Pensez aux dépendances
Je vais donc le résoudre un par un.
[Pushing point](#Pushing point) 1 et 2 sont résolus.
1 La condition d'un maximum de 6 de chaque côté est ignorée.
2 Aucune erreur ne se produit lorsque la longueur d'un côté est égale ou inférieure à 0.
Insérez ce qui suit au début de l'initialisation.
if w <= 0 || w > 6 {fatalError("w:\(w) not in 1...6")}
if h <= 0 || h > 6 {fatalError("h:\(h) not in 1...6")}
if d <= 0 || d > 6 {fatalError("d:\(d) not in 1...6")}
Résoudre [Pousser](# Pousser) 3.
Le volume et la taille ne changent pas même si la longueur des trois côtés est modifiée.
Parce que je veux changer le volume et la taille lorsque les valeurs de hauteur et de largeur changent Ajoutez ** willSet ** et ** didSet ** à chaque propriété et définissez-y le volume et la taille.
La validation signifie la vérification que vous pouvez définir la longueur que vous souhaitez modifier, donc avant de la définir. Après le réglage, le volume et la taille changeront en raison du changement de longueur.
--willSet: Validation --detSet: jeu de volume et de taille
var width: Int{
willSet{
if newValue<= 0 || newValue> 6 {fatalError("<width: \(newValue)> not in 1...6")}
}
didSet{
_volume = width * height * depth
switch _volume{
case 1...8:
_size = .S
case 9...64:
_size = .M
default:
_size = .L
}
}
}
var height: Int{
willSet{
if newValue<= 0 || newValue> 6 {fatalError("<height: \(newValue)> not in 1...6")}
}
didSet{
_volume = width * height * depth
switch _volume{
case 1...8:
_size = .S
case 9...64:
_size = .M
default:
_size = .L
}
}
}
var depth: Int{
willSet{
if newValue<= 0 || newValue> 6 {fatalError("<depth: \(newValue)> not in 1...6")}
}
didSet{
_volume = width * height * depth
switch _volume{
case 1...8:
_size = .S
case 9...64:
_size = .M
default:
_size = .L
}
}
}
[Pushing point](#Pushing point) Résout 4 et 5.
4 Le volume peut être modifié de l'extérieur. 5 La taille peut être modifiée de l'extérieur.
Le définir sur Propriété en lecture seule rend impossible la définition.
private var _volume: Int
private var _size: Size
var volume: Int {
get {
return _volume
}
}
var size: Size {
get {
return _size
}
}
.. .. .. Le code est aussi redondant que vous pouvez l'imaginer.
class IntBox{
enum Size{
case S, M, L
}
private var _volume: Int
private var _size: Size
var width: Int{
willSet{
if newValue<= 0 || newValue> 6 {fatalError("<width: \(newValue)> not in 1...6")}
}
didSet{
_volume = width * height * depth
switch _volume{
case 1...8:
_size = .S
case 9...64:
_size = .M
default:
_size = .L
}
}
}
var height: Int{
willSet{
if newValue<= 0 || newValue> 6 {fatalError("<height: \(newValue)> not in 1...6")}
}
didSet{
_volume = width * height * depth
switch _volume{
case 1...8:
_size = .S
case 9...64:
_size = .M
default:
_size = .L
}
}
}
var depth: Int{
willSet{
if newValue<= 0 || newValue> 6 {fatalError("<depth: \(newValue)> not in 1...6")}
}
didSet{
_volume = width * height * depth
switch _volume{
case 1...8:
_size = .S
case 9...64:
_size = .M
default:
_size = .L
}
}
}
var volume: Int {
get {
return _volume
}
}
var size: Size {
get {
return _size
}
}
init(w: Int, h: Int, d: Int){
if w <= 0 || w > 6 {fatalError("<w: \(w)> not in 1...6")}
if h <= 0 || h > 6 {fatalError("<h: \(h)> not in 1...6")}
if d <= 0 || d > 6 {fatalError("<d: \(d)> not in 1...6")}
width = w
height = h
depth = d
_volume = w * h * d
switch _volume{
case 1...8:
_size = .S
case 9..<64:
_size = .M
default:
_size = .L
}
}
func printStatus(){
var status = """
---statut---
width: \(width)
height: \(height)
depth: \(depth)
volume: \(volume)
size: \(size)
"""
print(status)
}
}
let cb = IntBox(w: 1, h: 1, d: 1)
cb.printStatus()
//Essayez de changer la largeur
cb.width = 11
cb.printStatus()
Puisqu'il y a de nombreuses violations du principe DRY, je vais créer une fonction commune et la mettre ensemble.
private func lengthValidate(_ length: Int, _ name: String = "length"){
if length <= 0 || length > 6 { fatalError("<\(name): \(length)> not in 1...6") }
}
private func setStatus() {
setVolume()
setSize()
}
private func setVolume() {
_volume = width * height * depth
}
private func setSize(){
switch _volume{
case 1...8:
_size = .S
case 9...64:
_size = .M
default:
_size = .L
}
}
Ce serait bien si ** setStatus () ** pouvait être créé lorsque le volume ou la taille est référencé. Cependant, il n'y a pas de changement Je veux également éviter d'appeler ** setStatus () ** chaque fois que le volume ou la taille est référencé. Je veux appeler ** setStatus () ** une seule fois après avoir changé la hauteur et la largeur. ** private var shouldSetStatus: crée un Bool ** et évalue s'il faut appeler ** setStatus () **.
private var shouldSetStatus: Bool
var width: Int = 1 {
willSet { lengthValidate(newValue, "width") }
didSet { shouldSetStatus = true } // <-Changement
}
...
var volume: Int {
get {
if shouldSetStatus { setStatus() }
return _volume
}
}
...
private func setStatus() {
setVolume()
setSize()
shouldSetStatus = false // <-ajouter à
}
class IntBox{
enum Size{
case S, M, L
}
private var _volume: Int = 1
private var _size: Size = .S
private var shouldSetStatus: Bool = false
var width: Int = 1 {
willSet { lengthValidate(newValue, "width") }
didSet { shouldSetStatus = true }
}
var height: Int = 1 {
willSet { lengthValidate(newValue, "height") }
didSet { shouldSetStatus = true }
}
var depth: Int = 1 {
willSet { lengthValidate(newValue, "depth") }
didSet { shouldSetStatus = true }
}
var volume: Int {
get {
if shouldSetStatus { setStatus() }
return _volume
}
}
var size: Size {
get {
if shouldSetStatus { setStatus() }
return _size
}
}
init(w: Int, h: Int, d: Int){
lengthValidate(w, "w")
lengthValidate(h, "h")
lengthValidate(d, "d")
width = w
height = h
depth = d
setStatus()
}
private func lengthValidate(_ length: Int, _ name: String = "length"){
if length <= 0 || length > 6 { fatalError("<\(name): \(length)> not in 1...6") }
}
private func setStatus() {
setVolume()
setSize()
shouldSetStatus = false
}
private func setVolume() {
_volume = width * height * depth
}
private func setSize(){
switch _volume{
case 1...8:
_size = .S
case 9...64:
_size = .M
default:
_size = .L
}
}
//Code de vérification
func printStatus(){
let status = """
---statut---
width: \(width)
height: \(height)
depth: \(depth)
volume: \(volume)
size: \(size)
"""
print(status)
}
}
//Vérification
let cb = IntBox(w: 1, h: 2, d: 3)
cb.printStatus()
//Essayez de changer la largeur
cb.width = 5
cb.printStatus()
À l'origine, il a été conçu à partir d'un protocole abstrait afin que la valeur maximale d'un côté et l'évaluation de S, M, L puissent être modifiées de manière flexible. Concernant l'erreur, il ne s'agit que de ** fatalError ** sans utiliser ** Optional **, mais il vaut mieux renvoyer ** nil ** au moment de l'initialisation ou le séparer de l'erreur au moment du changement de longueur. Cela peut être bon. .. .. Une fois, j'ai écrit un article sur mes meilleurs efforts actuels. Un jour, je grandirai au point où cela semble être un article embarrassant. J'ai également passé 2 heures x 3 jours sur cet article. .. .. J'écrirai un article avec cospa à l'esprit.
Recommended Posts