结构体(二)

在定义了配送区域和实例化的值之后,你可能想知道如何使用这些值。就像使用字符串、数组和字典一样,使用点语法访问成员:

print(storeArea.radius) // 4.0

还可以使用点语法访问成员的成员:

 print(storeArea.center.x) // 2

类似于你可以使用点语法读取值,你也可以指定它们的值。如果一个批萨位置的配送半径变得更大,你可以将新值分配给现有的属性:

storeArea.radius = 250

常量和变量的语义在确定是否可以给属性分配值起着重要的作用。在这种情况下,你可以指定radius,因为你用var来声明它,另一方面,你使用let声明了center,所以你不能修改它。因此你的DeliveryArea结构允许一个比萨餐厅的配送范围被改变,但不能改变它的位置!

除了选择属性应该是变量或常量之外,如果你希望在它初始化之后修改它,你还必须将结构本身声明为一个变量:

let fixedArea = DeliveryArea(center: storeLocation, radius: 4)
// Error: Cannot assign to property
fixedArea.radius = 250

该代码导致编译器发生错误。因为你将fixedArea从一个常量变为一个var变量,使其可变。

现在,你已经了解了如何控制结构中属性的可变性。

方法

使用一些结构的功能,你现在可以做一个披萨配送范围的计算器,看起来像这样:

let areas = [
  DeliveryArea(center: Location(x: 2, y: 4), radius: 2.5),
  DeliveryArea(center: Location(x: 9, y: 7), radius: 4.5)
]

func isInDeliveryRange(_ location: Location) -> Bool {
  for area in areas {
    let distanceToStore =
      distance(from: (area.center.x, area.center.y),
                 to: (location.x, location.y))
    if distanceToStore < area.radius {
      return true
    } 
  }
  return false
}

let customerLocation1 = Location(x: 8, y: 1)
let customerLocation2 = Location(x: 5, y: 5)
print(isInDeliveryRange(customerLocation1)) // false
print(isInDeliveryRange(customerLocation2)) // true

在本例中,有一个数组区域和一个函数,它使用该数组来确定客户的位置是否在这些区域内。

在范围内是你想知道的关于某家餐厅的信息。如果送货区能告诉你餐馆能不能送货到一个地方,那就太好了。

就像一个结构可以有常量和变量一样,它也可以定义自己的函数。在你的playground上,定位配送区域的实现。在关闭大括号之前,添加以下代码:

func contains(_ location: Location) -> Bool {
  let distanceFromCenter =
    distance(from: (center.x, center.y),
               to: (location.x, location.y))
  return distanceFromCenter < radius
}

这定义了一个函数contains,它现在是DeliveryArea的成员。属于类型成员的函数称为方法。注意contains如何使用当前location的center和radius属性。这种对属性和其他成员的隐式访问使得方法与常规函数不同。你将在以后了解更多关于方法的知识。

就像其他结构成员一样,你可以使用点语法访问方法:

let area = DeliveryArea(center: Location(x: 5, y: 5), radius: 4.5)
let customerLocation = Location(x: 2, y: 2)
area.contains(customerLocation) // true

你可能感兴趣的:(结构体(二))