Swift - Methods in Structures

Introduction

Methods are not exclusive to classes.

Structures can also have methods.

Consider the example of the Chess structure:

enum StoneColor:String {
      case Black = "Black"
      case White = "White"
}

struct Chess {
    var row:Int
    var column:Int
    var color:StoneColor
}

You could add a printPosition() method to output the position of a stone on the Chess board:


struct Chess {
 var row:Int
 var column:Int
 var color:StoneColor

  func printPosition() {
      print ("[" + String(row) + "," + String (column) + "]")
  }
}

To use the printPosition() method, create an instance of the Chess structure and call the printPosition() method directly:

var stone1 = Chess (row:12, column:16, color:StoneColor.Black)
stone1.printPosition()  //[12,16]

Consider another method named move() , which moves the stone according to the specified rows and columns:


struct Chess {
     var row:Int          //0...18
     var column:Int       //0...18
     var color:StoneColor
    
     func printPosition() {
         print("[" + String(row) + "," + String(column) + "]")
     }
    
      func move(dRow: Int, dColumn: Int) {
          row += dRow
          column += dColumn
      }
}

However, the preceding method will not compile.

In Swift, the properties of a value type cannot be modified from within its instance method; and because a structure is a value type, and the preceding move() method is trying to modify the row and column properties, the preceding will fail.

To fix this, you need to explicitly indicate that the method is mutating, as shown here:


struct Chess {
   var row:Int          //0...18
   var column:Int       //0...18
   var color:StoneColor

   func printPosition() {
       print("[" + String(row) + "," + String(column) + "]")
   }
    
   mutating func move(dRow: Int, dColumn: Int) {
        row += dRow
        column += dColumn
   }
}

You can now move the stone by calling the move() method:

var stone1 = Chess (row:12, column:16, color:StoneColor.Black)
stone1.printPosition()
stone1.move(2, dColumn: 1)
stone1.printPosition()   //[14,17]

stone1 structure must be declared as a variable using the var keyword.

If stone1 is a constant declared using the let keyword, the move() method will cause an error:

let stone1  = Chess (row:12, column:16, color:StoneColor.Black)
stone1.printPosition()
stone1.move(2, dColumn: 1)   //error

This is because the move() method is attempting to modify an immutable structure.

Related Topic