轨道
/
Gleam
Gleam
/
练习
/
跟风者
跟风者

跟风者

学习练习

简介

带标签的字段

当自定义类型的变体包含数据时,它被称为记录,其中包含的每个值都位于一个_字段_中。

pub type Rectangle {
  Rectangle(
    Float, // The first field
    Float, // The second field
  )
}

为了提高可读性,Gleam 允许用名称给字段加上标签。

pub type Rectangle {
  Rectangle(
    width: Float,
    height: Float,
  )
}

使用标签可以以任意顺序向记录的构造函数提供实参。

let a = Rectangle(height: 10.0, width: 20.0)
let b = Rectangle(width: 20.0, height: 10.0)

a == b
// -> True

当自定义类型只有一个变体时,可以使用.label访问器语法来获取记录中的字段。

let rect = Rectangle(height: 10.0, width: 20.0)

rect.height // -> 10.0
rect.width  // -> 20.0

当自定义类型只有一个变体时,还可以使用记录更新语法,在现有记录的基础上创建一个新记录,并将其中的部分字段替换为新值。

let rect = Rectangle(height: 10.0, width: 20.0)
let tall_rect = Rectangle(..rect, height: 50.0)

tall_rect.height // -> 50.0
tall_rect.width  // -> 20.0

在模式匹配中提取记录的值时,也可以使用标签。

pub fn is_tall(rect: Rectangle) {
  case rect {
    Rectangle(height: h, width: _) if h >. 20.0 -> True
    _ -> False
  }
}

如果我们只想匹配其中一部分字段,可以使用展开运算符..来忽略其余字段。

pub fn is_tall(rect: Rectangle) {
  case rect {
    Rectangle(height: h, ..) if h >. 20.0 -> True
    _ -> False
  }
}

说明

在这个练习中,你是一位铁杆体育迷,刚刚迷上了 NBA 篮球。作为 NBA 篮球的新人,你正在深入研究 NBA 的历史,记录球队、教练和他们的胜负数据,并把它们互相比较。

由于你还没有最喜欢的球队,你还要开发一个算法,来判断是否该支持某支球队。

你有七个任务,帮你开发出自己专属的_支持某支球队_算法。

1. 定义模型

定义Coach记录,它包含以下两个字段:

  • name:教练的名字,类型为String。
  • former_player:表示这位教练是否曾是球员,类型为Bool。

定义Stats记录,它包含以下两个字段:

  • wins:获胜的场数,类型为Int。
  • losses:失利的场数,类型为Int。

定义Team记录,它包含以下三个字段:

  • name:球队的名字,类型为String。
  • coach:球队的教练,类型为Coach。
  • stats:球队的数据,类型为Stats。

2. 创建球队的教练

实现create_coach函数,它接收教练的名字以及是否曾是球员作为形参,并返回对应的Coach记录:

create_coach("Larry Bird", True)
// -> Coach(name: "Larry Bird", former_player: True)

3. 创建球队的数据

实现create_stats函数,它接收获胜场数和失利场数作为形参,并返回对应的Stats记录:

create_stats(58, 24)
// -> Stats(wins: 58, losses: 24)

4. 创建一支球队

实现create_team函数,它接收球队名字、教练和数据作为形参,并返回对应的Team记录:

let coach = create_coach("Larry Bird", True)
let stats = create_stats(58, 24)
create_team("Indiana Pacers", coach, stats)
// -> Team(
//   name: "Indiana Pacers",
//   coach: Coach(name: "Larry Bird", FormerPlayer = True),
//   stats: Stats(wins: 58, losses: 24),
// ) 

5. 更换教练

NBA 的老板们可没什么耐心,你会发现球队成绩不好往往会导致教练被换掉。实现replace_coach函数,它接收球队和它的新教练作为形参,并返回换了新教练之后的球队:

let coach = create_coach("Larry Bird", True)
let record = create_stats(58, 24)
let team = create_team("Indiana Pacers", coach, record)

let new_coach = create_coach("Isiah Thomas", True)
replace_coach(team, new_coach)
// -> Team(
//   name: "Indiana Pacers",
//   coach: Coach(name: "Isiah Thomas", FormerPlayer = True),
//   stats: Stats(wins: 58, losses: 24),
// ) 

6. 判断是否是同一支球队

在研究数据的过程中,你会记录球队和它们的数据列表。有时你会弄错,列表里就出现了重复的条目。实现is_same_team函数,它接收两支球队,如果它们是同一支球队就返回True,否则返回False:

let pacers_coach = create_coach("Larry Bird", True)
let pacers_stats = create_stats(58, 24)
let pacers_team = create_team("Indiana Pacers", pacers_coach, pacers_stats)

let lakers_coach = create_coach("Del Harris", False)
let lakers_stats = create_stats(61, 21)
let lakers_team = create_team("LA Lakers", lakers_coach, lakers_stats)

is_same_team(pacers_team, lakers_team)
// -> False

7. 判断是否该支持某支球队

看过很多球队和比赛之后,你想出了一个算法。只要满足以下任意一条,你就支持那支球队:

  • 教练的名字是 "Gregg Popovich"
  • 教练曾是球员
  • 球队的名字是 "Chicago Bulls"
  • 球队赢了 60 场或更多比赛
  • 球队的失利场数多于获胜场数

实现root_for_team函数,它接收一支球队,如果你该支持这支球队就返回True,否则返回False:

let spurs_coach = create_coach("Gregg Popovich", False)
let spurs_stats = create_stats(56, 26)
let spurs_team = create_team("San Antonio Spurs", spurs_coach, spurs_stats)
root_for_team(spurs_team)
// -> True
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Gleam Exercism

准备好开始 跟风者 了吗?

注册 Exercism,借助 33 个概念122 个练习 和真人导师指导,学习并掌握 Gleam,全部免费。