Menu
CoddyTech

Xác thực bằng phương thức setter

Thuộc phần Lập trình hướng đối tượng trong hành trình GDScript của Coddy. Bài học 27 trên 65.

Setter chạy mỗi khi thuộc tính của nó được gán giá trị, nên đây là nơi để kiểm tra giá trị mới. Python báo lỗi khi giá trị không hợp lệ. GDScript không có ngoại lệ, vì vậy setter sẽ làm một trong hai việc: giới hạn giá trị trong phạm vi cho phép, hoặc giữ giá trị cũ và ghi lại lỗi đã xảy ra.

# character.gd
class_name Character
extends RefCounted

var last_error: String = ""
var hp: int = 100:
	set(value):
		hp = clampi(value, 0, 100)
var nickname: String = "Player":
	set(value):
		if value.length() < 3:
			last_error = "Name too short"
			return
		last_error = ""
		nickname = value

clampi(value, 0, 100) đưa value vào phạm vi từ 0 đến 100. Trong setter nickname, return thoát trước khi gán, nên tên cũ vẫn được giữ nguyên và last_error giải thích lý do:

# main.gd
var hero := Character.new()
hero.hp = 250
print(hero.hp) # 100
hero.nickname = "Al"
print(hero.nickname) # Player
print(hero.last_error) # Tên quá ngắn
hero.nickname = "Alice"
print(hero.nickname) # Alice

Setter cũng chạy với các phép gán bên trong lớp, trong _init() và trong mọi phương thức. Hãy gán các đối số của hàm khởi tạo thông qua thuộc tính để chúng cũng được kiểm tra:

func _init(start_hp: int) -> void:
	hp = start_hp # gọi hàm setter: Character.new(500) bắt đầu với 100

Bên trong chính setter, việc gán hp sẽ lưu giá trị mà không gọi lại setter. Lần gán duy nhất bỏ qua setter là giá trị ban đầu trong phần khai báo (= 100), vì vậy giá trị đó phải hợp lệ.

challenge icon

Thử thách

Dễ

Thêm kiểm tra hợp lệ vào lớp Thermostat trong thermostat.gd bằng các setter:

  • target (ban đầu là 20) chỉ chấp nhận các giá trị từ 10 đến 30. Với mọi giá trị khác, thuộc tính này giữ nguyên target cũ và đặt last_error thành Target must be between 10 and 30.
  • mode (ban đầu là off) chỉ chấp nhận heat, cool và off. Với mọi văn bản khác, thuộc tính này giữ nguyên mode cũ và đặt last_error thành Unknown mode: theo sau là văn bản đó.
  • Mỗi lần gán hợp lệ sẽ đặt lại last_error thành chuỗi rỗng.
  • _init(start_target) gán start_target cho target, để setter kiểm tra giá trị đó.

Code được cung cấp đọc target ban đầu, sau đó đọc số lệnh, rồi đọc từng lệnh trên một dòng (target 25 hoặc mode cool). Sau khi tạo bộ điều nhiệt và sau mỗi lệnh, chương trình in ra Rejected: cùng với lỗi nếu last_error không rỗng, rồi in ra trạng thái. Với giá trị bắt đầu là 22 và các lệnh target 35 và mode cool, chương trình in ra:

Target 22, mode off
Rejected: Target must be between 10 and 30
Target 22, mode off
Target 22, mode cool

Code của bạn nằm trong thermostat.gd. main.gd chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.

Tự làm thử

extends Node

func _ready():
	# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
	var thermostat := Thermostat.new(int(OS.read_string_from_stdin()))
	report(thermostat)
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		if parts[0] == "target":
			thermostat.target = int(parts[1])
		else:
			thermostat.mode = parts[1]
		report(thermostat)

func report(thermostat: Thermostat) -> void:
	if thermostat.last_error != "":
		print("Rejected: " + thermostat.last_error)
	print("Target %d, mode %s" % [thermostat.target, thermostat.mode])
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch GDScript online