ΠΠ°ΡΡΠΎΠΌΠ½ΡΠ΅ ΡΠΈΠΏΡ Π² Go ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡ ΡΠΎΠ±ΠΎΠΉ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΡΠ°ΠΌΡΡ
ΠΌΠΎΡΠ½ΡΡ
ΠΌΠ΅Ρ
Π°Π½ΠΈΠ·ΠΌΠΎΠ² ΡΠ·ΡΠΊΠ° Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π²ΡΡΠ°Π·ΠΈΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ, Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΠ³ΠΎ ΠΈ ΡΠ°ΠΌΠΎΠ΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΈΡΡΡΡΠ΅Π³ΠΎΡΡ ΠΊΠΎΠ΄Π°. ΠΠΌΠ΅ΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²Π½ΡΡ
ΡΠΈΠΏΠΎΠ² Π²ΡΠΎΠ΄Π΅ int
, string
ΠΈΠ»ΠΈ float64
ΠΏΠΎΠ²ΡΡΠ΄Ρ Π² ΠΊΠΎΠ΄Π΅, ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΌΠΎΠ³ΡΡ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ ΡΠΈΠΏΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ΡΡΡ ΡΠ΅ΠΌΠ°Π½ΡΠΈΡΠ΅ΡΠΊΡΡ Π½Π°Π³ΡΡΠ·ΠΊΡ ΠΈ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ°ΡΡ ΡΠ΅Π»ΡΠ΅ ΠΊΠ»Π°ΡΡΡ ΠΎΡΠΈΠ±ΠΎΠΊ Π½Π° ΡΡΠ°ΠΏΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ.
Π ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ΅ Π½Π° Go ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠ΅ ΡΠΈΠΏΡ ΡΡΠ°Π»ΠΈ ΡΡΠ°Π½Π΄Π°ΡΡΠΎΠΌ ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°. ΠΠ½ΠΈ Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π΅Π»Π°ΡΡ ΠΊΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ ΡΠΈΡΠ°Π΅ΠΌΡΠΌ, Π½ΠΎ ΠΈ ΡΠΎΠ·Π΄Π°ΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΡΡΠΎΠ²Π΅Π½Ρ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ ΡΠΈΠΏΠΎΠ², ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°ΡΡ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ Π΅ΡΠ΅ Π΄ΠΎ Π·Π°ΠΏΡΡΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ.
π― Π€ΡΠ½Π΄Π°ΠΌΠ΅Π½ΡΠ°Π»ΡΠ½ΡΠ΅ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π° ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΡ ΡΠΈΠΏΠΎΠ²
Π‘Π΅ΠΌΠ°Π½ΡΠΈΡΠ΅ΡΠΊΠ°Ρ ΡΡΠ½ΠΎΡΡΡ ΠΊΠΎΠ΄Π°
ΠΠΎΠ³Π΄Π° Π²Ρ Π²ΠΈΠ΄ΠΈΡΠ΅ ΡΡΠ½ΠΊΡΠΈΡ ProcessPayment(amount float64)
, Π½Π΅ΡΡΠ½ΠΎ, Π² ΠΊΠ°ΠΊΠΈΡ
Π΅Π΄ΠΈΠ½ΠΈΡΠ°Ρ
ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΡ amount β Π² ΡΡΠ±Π»ΡΡ
, Π΄ΠΎΠ»Π»Π°ΡΠ°Ρ
, ΠΊΠΎΠΏΠ΅ΠΉΠΊΠ°Ρ
? Π ΡΡΠ½ΠΊΡΠΈΡ ProcessPayment(amount Money)
ΡΡΠ°Π·Ρ Π΄Π°Π΅Ρ ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΡΠΎΠ³ΠΎ, ΡΡΠΎ amount β ΡΡΠΎ Π΄Π΅Π½Π΅ΠΆΠ½Π°Ρ ΡΡΠΌΠΌΠ° ΡΠΎ Π²ΡΠ΅ΠΉ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅ΠΉ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ.
ΠΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ΅Π½ΠΈΠ΅ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΡ ΠΎΡΠΈΠ±ΠΎΠΊ
ΠΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΏΡΠΈΠΌΠ΅Ρ β ΡΡΠ½ΠΊΡΠΈΡ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄Π° Π΄Π΅Π½Π΅Π³. ΠΡΠ΅Π΄ΡΡΠ°Π²ΡΡΠ΅:
TransferMoney(123, 456, 1000) // Π§ΡΠΎ ΠΎΠ·Π½Π°ΡΠ°ΡΡ ΡΡΠΈ ΡΠΈΡΠ»Π°?
ΠΡΠΎΡΠΈΠ²:
TransferMoney(UserID(123), UserID(456), Money(1000)) // ΠΡΠΈΡΡΠ°Π»ΡΠ½ΠΎ ΡΡΠ½ΠΎ!
Π‘ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠΌΠΈ ΡΠΈΠΏΠ°ΠΌΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ ΡΠΈΠ·ΠΈΡΠ΅ΡΠΊΠΈ Π½Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ Π²Π°ΠΌ ΠΏΠ΅ΡΠ΅ΠΏΡΡΠ°ΡΡ ΠΏΠΎΡΡΠ΄ΠΎΠΊ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ² ΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π½Π΅ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈΠΉ ΡΠΈΠΏ.
ΠΠ½ΠΊΠ°ΠΏΡΡΠ»ΡΡΠΈΡ Π±ΠΈΠ·Π½Π΅Ρ-Π»ΠΎΠ³ΠΈΠΊΠΈ
ΠΠ°ΡΡΠΎΠΌΠ½ΡΠ΅ ΡΠΈΠΏΡ ΠΌΠΎΠ³ΡΡ ΠΈΠΌΠ΅ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΠ½ΠΊΠ°ΠΏΡΡΠ»ΠΈΡΡΡΡ ΡΠ²ΡΠ·Π°Π½Π½ΡΡ Ρ ΡΠΈΠΏΠΎΠΌ Π»ΠΎΠ³ΠΈΠΊΡ. Email ΠΌΠΎΠΆΠ΅Ρ Π²Π°Π»ΠΈΠ΄ΠΈΡΠΎΠ²Π°ΡΡ ΡΠ΅Π±Ρ, Money β ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ Π²Π°Π»ΡΡΡ, Temperature β ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΠΈΡΡ Π΅Π΄ΠΈΠ½ΠΈΡΡ ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΡ.
π¬ Π Π΅Π°Π»ΡΠ½Π°Ρ ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠ° ΠΈΠ· ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ
Π ΠΎΠ΄Π½ΠΎΠΌ ΠΊΡΡΠΏΠ½ΠΎΠΌ ΡΠΈΠ½ΡΠ΅Ρ -ΠΏΡΠΎΠ΅ΠΊΡΠ΅ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄ Π½Π° ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠ΅ ΡΠΈΠΏΡ Π΄Π»Ρ Π΄Π΅Π½Π΅ΠΆΠ½ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ ΡΠΎΠΊΡΠ°ΡΠΈΠ» ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π±Π°Π³ΠΎΠ² Π½Π° 40% ΠΈ Π²ΡΠ΅ΠΌΡ Π½Π° code review Π½Π° 25%, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΊΠΎΠ΄ ΡΡΠ°Π» ΡΠ°ΠΌΠΎΠΎΠ±ΡΡΡΠ½ΡΡΡΠΈΠΌΡΡ.
π― Π‘ΠΈΠ½ΡΠ°ΠΊΡΠΈΡ ΠΈ ΠΎΡΠ½ΠΎΠ²Ρ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΡ ΡΠΈΠΏΠΎΠ²
Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠ°ΡΡΠΎΠΌΠ½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° Π² Go Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ³ΠΎ ΡΠ»ΠΎΠ²Π° type
. Π‘ΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ ΡΡΠΎ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΠΏΡΠΎΡΡΠΎ, Π½ΠΎ Π·Π° ΡΡΠΎΠΉ ΠΏΡΠΎΡΡΠΎΡΠΎΠΉ ΡΠΊΡΡΠ²Π°Π΅ΡΡΡ ΠΌΠΎΡΠ½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° ΡΠΈΠΏΠΎΠ², ΠΊΠΎΡΠΎΡΠ°Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ ΠΊΠ°ΠΊ Π³ΠΈΠ±ΠΊΠΎΡΡΡ, ΡΠ°ΠΊ ΠΈ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ.
Π€ΠΈΠ»ΠΎΡΠΎΡΠΈΡ ΡΠΈΠΏΠΎΠ² Π² Go
Go ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π½ΠΎΠΌΠΈΠ½Π°Π»ΡΠ½ΡΡ ΡΠΈΡΡΠ΅ΠΌΡ ΡΠΈΠΏΠΎΠ², ΡΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ: Π΄Π²Π° ΡΠΈΠΏΠ° ΡΡΠΈΡΠ°ΡΡΡΡ ΡΠ°Π·Π½ΡΠΌΠΈ, Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ Ρ Π½ΠΈΡ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Π°Ρ Π²Π½ΡΡΡΠ΅Π½Π½ΡΡ ΡΡΡΡΠΊΡΡΡΠ°, Π΅ΡΠ»ΠΈ ΠΎΠ½ΠΈ ΠΎΠ±ΡΡΠ²Π»Π΅Π½Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎ. ΠΡΠΎ ΠΊΠ°ΡΠ΄ΠΈΠ½Π°Π»ΡΠ½ΠΎ ΠΎΡΠ»ΠΈΡΠ°Π΅ΡΡΡ ΠΎΡ ΡΡΡΡΠΊΡΡΡΠ½ΠΎΠΉ ΡΠΈΠΏΠΈΠ·Π°ΡΠΈΠΈ ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ.
ΠΠΎΠ³Π΄Π° Π²Ρ ΡΠΎΠ·Π΄Π°Π΅ΡΠ΅ type UserID int
, Π²Ρ ΡΠΎΠ·Π΄Π°Π΅ΡΠ΅ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π½ΠΎΠ²ΡΠΉ ΡΠΈΠΏ, ΠΊΠΎΡΠΎΡΡΠΉ:
- ΠΠΌΠ΅Π΅Ρ ΡΠ΅ ΠΆΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ, ΡΡΠΎ ΠΈ
int
(ΡΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π²ΡΡΠΈΡΠ°Π½ΠΈΠ΅, ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅) - ΠΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π½Π°ΠΏΡΡΠΌΡΡ ΠΏΡΠΈΡΠ²ΠΎΠ΅Π½ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΡΠΈΠΏΠ°
int
Π±Π΅Π· ΡΠ²Π½ΠΎΠ³ΠΎ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΡ - ΠΠΎΠΆΠ΅Ρ ΠΈΠΌΠ΅ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ
- Π£ΡΠ°ΡΡΠ²ΡΠ΅Ρ Π² ΠΏΡΠΎΠ²Π΅ΡΠΊΠ΅ ΡΠΈΠΏΠΎΠ² Π½Π° ΡΡΠ°ΠΏΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ
Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡΠΎΡΡΡΡ ΡΠΈΠΏΠΎΠ²
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π±Π°Π·ΠΎΠ²ΡΡ
ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΡ
ΡΠΈΠΏΠΎΠ²
type UserID int
type ProductID int
type Email string
type PhoneNumber string
func main() {
var userID UserID = 123
var productID ProductID = 456
// ΠΡΠΈΠ±ΠΊΠ° ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ: Π½Π΅Π»ΡΠ·Ρ ΠΏΡΠΈΡΠ²ΠΎΠΈΡΡ Π½Π°ΠΏΡΡΠΌΡΡ
// userID = productID
// Π’ΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠ²Π½ΠΎΠ΅ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΠ΅
userID = UserID(productID)
}
ΠΠ»ΡΡΠ΅Π²ΡΠ΅ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ ΡΠΈΠΏΠΈΠ·Π°ΡΠΈΠΈ
ΠΡΠΎΡ ΠΏΡΠΎΡΡΠΎΠΉ ΠΏΡΠΈΠΌΠ΅Ρ Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΠ΅Ρ ΡΡΠ½Π΄Π°ΠΌΠ΅Π½ΡΠ°Π»ΡΠ½ΡΠ΅ ΠΏΡΠΈΠ½ΡΠΈΠΏΡ:
ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ ΡΠΈΠΏΠΎΠ²: ΠΠΎΠΏΡΡΠΊΠ° ΠΏΡΠΈΡΠ²ΠΎΠΈΡΡ
productID
Π½Π°ΠΏΡΡΠΌΡΡ Π²userID
Π²ΡΠ·ΠΎΠ²Π΅Ρ ΠΎΡΠΈΠ±ΠΊΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ, ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ°Ρ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ.Π―Π²Π½ΠΎΠ΅ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΠ΅:
UserID(productID)
β ΡΡΠΎ Π½Π΅ ΠΏΡΠΎΡΡΠΎ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΠΈΠΏΠΎΠ², Π° ΡΠ²Π½ΠΎΠ΅ Π·Π°ΡΠ²Π»Π΅Π½ΠΈΠ΅ ΠΎ ΡΠΎΠΌ, ΡΡΠΎ Π²Ρ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅ΡΠ΅ ΡΠ΅ΠΌΠ°Π½ΡΠΈΠΊΡ ΡΡΠΎΠ³ΠΎ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΡ.ΠΠ°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ: ΠΠ°ΡΡΠΎΠΌΠ½ΡΠ΅ ΡΠΈΠΏΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΠΎΠ»ΡΡΠ°ΡΡ Π²ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° β Π°ΡΠΈΡΠΌΠ΅ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅, ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ, ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅.
Π§ΠΈΡΠ°Π΅ΠΌΠΎΡΡΡ ΠΊΠΎΠ΄Π°:
Email
ΠΈPhoneNumber
ΡΡΠ°Π·Ρ Π΄Π°ΡΡ ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π°Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ.
Π ΠΏΡΠΎΠ΄Π°ΠΊΡΠ΅Π½Π΅ ΡΠ°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈ Π²Π°ΠΆΠ΅Π½. ΠΡΠ΅Π΄ΡΡΠ°Π²ΡΡΠ΅ e-commerce ΡΠΈΡΡΠ΅ΠΌΡ, Π³Π΄Π΅ ΠΏΠ΅ΡΠ΅ΠΏΡΡΠ°ΡΡ ID ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΠΈ ID ΠΏΡΠΎΠ΄ΡΠΊΡΠ° ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠ²Π΅ΡΡΠΈ ΠΊ ΡΠ΅ΡΡΠ΅Π·Π½ΡΠΌ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΠ²ΠΈΡΠΌ.
ποΈ ΠΠ΅ΡΠΎΠ΄Ρ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΡ ΡΠΈΠΏΠΎΠ²
ΠΠ΄Π½Π° ΠΈΠ· ΡΠ°ΠΌΡΡ ΠΌΠΎΡΠ½ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠ΅ΠΉ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΡ ΡΠΈΠΏΠΎΠ² β ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΡ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΠΊ Π½ΠΈΠΌ ΠΌΠ΅ΡΠΎΠ΄Ρ. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΈΠ½ΠΊΠ°ΠΏΡΡΠ»ΠΈΡΠΎΠ²Π°ΡΡ Π»ΠΎΠ³ΠΈΠΊΡ, ΡΠ²ΡΠ·Π°Π½Π½ΡΡ Ρ ΡΠΈΠΏΠΎΠΌ, ΠΈ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ rich domain models ΠΏΡΡΠΌΠΎ Π² ΡΠΈΡΡΠ΅ΠΌΠ΅ ΡΠΈΠΏΠΎΠ² Go.
ΠΡΠΈΠ½ΡΠΈΠΏΡ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ²
ΠΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² Π΄Π»Ρ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΡ ΡΠΈΠΏΠΎΠ² Π²Π°ΠΆΠ½ΠΎ ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ ΠΏΡΠΈΠ½ΡΠΈΠΏΠ°ΠΌ:
- ΠΠ΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½Π°Ρ ΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎΡΡΡ: ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ ΡΠ΅ΡΠ°Π΅Ρ ΠΎΠ΄Π½Ρ Π·Π°Π΄Π°ΡΡ
- Immutability: ΠΌΠ΅ΡΠΎΠ΄Ρ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ
- ΠΠΎΠΌΠΏΠΎΠ·ΠΈΡΠΈΡ: ΡΠ»ΠΎΠΆΠ½ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΡΡΡΠΎΡΡΡΡ ΠΈΠ· ΠΏΡΠΎΡΡΡΡ
- Defensive programming: ΠΌΠ΅ΡΠΎΠ΄Ρ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ Π½Π΅ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅
type Email string
// ΠΠ΅ΡΠΎΠ΄Ρ Π΄Π»Ρ Email ΡΠΈΠΏΠ°
func (e Email) IsValid() bool {
return strings.Contains(string(e), "@") && strings.Contains(string(e), ".")
}
func (e Email) GetDomain() string {
parts := strings.Split(string(e), "@")
if len(parts) != 2 {
return ""
}
return parts[1]
}
func (e Email) Normalize() Email {
return Email(strings.ToLower(string(e)))
}
// ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅
email := Email("USER@Example.COM")
if email.IsValid() {
normalized := email.Normalize()
domain := normalized.GetDomain()
}
ΠΠ°ΡΡΠ΅ΡΠ½Ρ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ²
1. Fluent Interface (Π¦Π΅ΠΏΠΎΡΠΊΠ° Π²ΡΠ·ΠΎΠ²ΠΎΠ²):
user := NewUser("John").
SetEmail("john@example.com").
SetAge(30).
SetRole("admin")
2. Builder Pattern:
type UserBuilder struct {
user User
}
func (b *UserBuilder) WithEmail(email Email) *UserBuilder {
b.user.Email = email
return b
}
func (b *UserBuilder) Build() User {
return b.user
}
3. Validation Methods:
func (u User) Validate() error {
if !u.Email.IsValid() {
return errors.New("invalid email")
}
return nil
}
π‘οΈ Π’ΠΈΠΏΡ Π΄Π»Ρ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ
ΠΠ°ΡΡΠΎΠΌΠ½ΡΠ΅ ΡΠΈΠΏΡ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ ΡΠ΅Π½Π½Ρ Π² ΡΠΈΠ½Π°Π½ΡΠΎΠ²ΡΡ ΠΈ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈ Π²Π°ΠΆΠ½ΡΡ ΡΠΈΡΡΠ΅ΠΌΠ°Ρ , Π³Π΄Π΅ ΠΎΡΠΈΠ±ΠΊΠΈ ΡΠΈΠΏΠΎΠ² ΠΌΠΎΠ³ΡΡ ΠΈΠΌΠ΅ΡΡ ΡΠ΅ΡΡΠ΅Π·Π½ΡΠ΅ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΠ²ΠΈΡ.
Π€ΠΈΠ½Π°Π½ΡΠΎΠ²ΡΠ΅ ΡΠΈΠΏΡ
// ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΡΠ΅ Π΄Π΅Π½Π΅ΠΆΠ½ΡΠ΅ ΡΠΈΠΏΡ
type Money int64 // Ρ
ΡΠ°Π½Π΅Π½ΠΈΠ΅ Π² ΡΠ΅Π½ΡΠ°Ρ
/ΠΊΠΎΠΏΠ΅ΠΉΠΊΠ°Ρ
type Currency string
type UserID int64
type Amount struct {
Value Money
Currency Currency
}
// ΠΠ΅ΡΠΎΠ΄Ρ Π΄Π»Ρ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΠΉ ΡΠ°Π±ΠΎΡΡ Ρ Π΄Π΅Π½ΡΠ³Π°ΠΌΠΈ
func (a Amount) Add(other Amount) (Amount, error) {
if a.Currency != other.Currency {
return Amount{}, errors.New("currency mismatch")
}
return Amount{Value: a.Value + other.Value, Currency: a.Currency}, nil
}
// ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄Π°
func TransferMoney(from, to UserID, amount Amount) error {
if from == to {
return errors.New("self-transfer not allowed")
}
if amount.Value <= 0 {
return errors.New("amount must be positive")
}
// ΠΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄...
return nil
}
ΠΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ½ΡΠ΅ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π°
1. ΠΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΡΠΌΠ΅ΡΠΈΠ²Π°Π½ΠΈΡ Π΅Π΄ΠΈΠ½ΠΈΡ ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΡ:
Money
Π² ΡΠ΅Π½ΡΠ°Ρ ΠΈΡΠΊΠ»ΡΡΠ°Π΅Ρ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΎΠΊΡΡΠ³Π»Π΅Π½ΠΈΡCurrency
ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ°Π΅Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠ°Π·Π½ΡΠΌΠΈ Π²Π°Π»ΡΡΠ°ΠΌΠΈ- ΠΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ Π½Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ
OrderID
Π²ΠΌΠ΅ΡΡΠΎUserID
2. Π‘Π°ΠΌΠΎΠ΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΈΡΡΡΡΠΈΠΉΡΡ ΠΊΠΎΠ΄:
// ΠΠΎΠ½ΡΡΠ½ΠΎ Π±Π΅Π· ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠ΅Π²
func CalculateCommission(amount Money, rate Percentage) Money
func GetUserOrders(userID UserID) []Order
func UpdateProductPrice(productID ProductID, newPrice Money)
3. ΠΡΠ»ΠΎΠ² ΠΎΡΠΈΠ±ΠΎΠΊ Π½Π° ΡΡΠ°ΠΏΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ:
userID := UserID(123)
orderID := OrderID(456)
// ΠΡΠΈΠ±ΠΊΠ° ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ - ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ Π·Π°ΡΠΈΡΠ°Π΅Ρ ΠΎΡ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΡ
ΠΎΡΠΈΠ±ΠΎΠΊ
// ProcessUser(orderID) // ΠΠ΅Π»ΡΠ·Ρ!
ProcessUser(userID) // ΠΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎ
Domain-Driven Design Ρ ΡΠΈΠΏΠ°ΠΌΠΈ
ΠΠ°ΡΡΠΎΠΌΠ½ΡΠ΅ ΡΠΈΠΏΡ ΠΈΠ΄Π΅Π°Π»ΡΠ½ΠΎ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡ Π΄Π»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ DDD ΠΊΠΎΠ½ΡΠ΅ΠΏΡΠΈΠΉ:
Value Objects:
type Email string
type PhoneNumber string
type Address struct {
Street string
City string
PostCode string
}
Entity IDs:
type CustomerID string
type ProductID int64
type OrderID uuid.UUID
Business Rules Π² ΡΠΈΠΏΠ°Ρ :
type Age int
func NewAge(value int) (Age, error) {
if value < 0 || value > 150 {
return 0, errors.New("invalid age")
}
return Age(value), nil
}
π’ Enum-ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠ΅ ΡΠΈΠΏΡ
Go Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠ³ΠΎ enum ΡΠΈΠΏΠ°, Π½ΠΎ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠ΅ ΡΠΈΠΏΡ Ρ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΠ°ΠΌΠΈ ΡΠ»Π΅Π³Π°Π½ΡΠ½ΠΎ ΡΠ΅ΡΠ°ΡΡ ΡΡΡ Π·Π°Π΄Π°ΡΡ.
Π§ΠΈΡΠ»ΠΎΠ²ΡΠ΅ Enum Ρ iota
type OrderStatus int
const (
Pending OrderStatus = iota
Processing
Shipped
Delivered
Cancelled
)
func (s OrderStatus) String() string {
names := []string{"Pending", "Processing", "Shipped", "Delivered", "Cancelled"}
if s < 0 || int(s) >= len(names) {
return "Unknown"
}
return names[s]
}
func (s OrderStatus) CanCancel() bool {
return s == Pending || s == Processing
}
Π‘ΡΡΠΎΠΊΠΎΠ²ΡΠ΅ Enum
type Role string
const (
Admin Role = "admin"
Moderator Role = "moderator"
User Role = "user"
Guest Role = "guest"
)
func (r Role) HasPermission(action string) bool {
permissions := map[Role][]string{
Admin: {"read", "write", "delete", "admin"},
Moderator: {"read", "write", "moderate"},
User: {"read", "write"},
Guest: {"read"},
}
for _, perm := range permissions[r] {
if perm == action {
return true
}
}
return false
}
ΠΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π° Enum ΡΠΈΠΏΠΎΠ² Π² Go
1. Type Safety: ΠΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π΅ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ
2. Π Π°ΡΡΠΈΡΡΠ΅ΠΌΠΎΡΡΡ: ΠΠ΅Π³ΠΊΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π½ΠΎΠ²ΡΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ Π±Π΅Π· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΠΊΠΎΠ΄Π°
3. ΠΠ΅ΡΠΎΠ΄Ρ Π΄Π»Ρ Π±ΠΈΠ·Π½Π΅Ρ-Π»ΠΎΠ³ΠΈΠΊΠΈ:
func (s OrderStatus) NextStatus() OrderStatus {
switch s {
case Pending:
return Processing
case Processing:
return Shipped
case Shipped:
return Delivered
default:
return s // ΠΠ΅Π»ΡΠ·Ρ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ ΡΡΠ°ΡΡΡ
}
}
4. ΠΠ°Π»ΠΈΠ΄Π°ΡΠΈΡ:
func NewOrderStatus(value int) (OrderStatus, error) {
if value < int(Pending) || value > int(Cancelled) {
return 0, errors.New("invalid order status")
}
return OrderStatus(value), nil
}
π¨ Π’ΠΈΠΏΡ Ρ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠ΅ΠΉ
ΠΠ°ΡΡΠΎΠΌΠ½ΡΠ΅ ΡΠΈΠΏΡ ΠΌΠΎΠ³ΡΡ ΠΈΠ½ΠΊΠ°ΠΏΡΡΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΡΠ»ΠΎΠΆΠ½ΡΡ Π»ΠΎΠ³ΠΈΠΊΡ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ ΠΈ ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ, ΡΠΎΠ·Π΄Π°Π²Π°Ρ ΡΠ°ΠΌΠΎΠΏΡΠΎΠ²Π΅ΡΡΡΡΠΈΠ΅ΡΡ value objects.
ΠΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΡ Ρ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠ΅ΠΉ
type Email string
func NewEmail(raw string) (Email, error) {
if !strings.Contains(raw, "@") || !strings.Contains(raw, ".") {
return "", errors.New("invalid email format")
}
return Email(strings.ToLower(raw)), nil
}
type Password string
func NewPassword(raw string) (Password, error) {
if len(raw) < 8 {
return "", errors.New("password too short")
}
hasUpper := regexp.MustCompile(`[A-Z]`).MatchString(raw)
hasLower := regexp.MustCompile(`[a-z]`).MatchString(raw)
hasDigit := regexp.MustCompile(`\d`).MatchString(raw)
if !hasUpper || !hasLower || !hasDigit {
return "", errors.New("password must contain upper, lower, and digit")
}
return Password(raw), nil
}
ΠΠ°ΡΡΠ΅ΡΠ½ “Smart Constructor”
ΠΡΠΎΡ ΠΏΠ°ΡΡΠ΅ΡΠ½ Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ, ΡΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ Π²ΡΠ΅Π³Π΄Π° Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² Π²Π°Π»ΠΈΠ΄Π½ΠΎΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ:
1. ΠΡΠΈΠ²Π°ΡΠ½ΡΠΉ ΡΠΈΠΏ + ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΉ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ:
type validatedEmail struct {
value string
}
func NewEmail(raw string) (*validatedEmail, error) {
// ΠΠ°Π»ΠΈΠ΄Π°ΡΠΈΡ...
return &validatedEmail{value: clean}, nil
}
func (e *validatedEmail) String() string {
return e.value // ΠΠ°ΡΠ°Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎ Π²Π°Π»ΠΈΠ΄Π½ΡΠΉ
}
2. ΠΠ΅ΡΠΎΠ΄Ρ Π΄Π»Ρ ΡΡΠ°Π½ΡΡΠΎΡΠΌΠ°ΡΠΈΠΈ:
func (e Email) Normalize() Email {
return Email(strings.ToLower(string(e)))
}
func (p PhoneNumber) Format() string {
// ΠΡΠ°ΡΠΈΠ²ΠΎΠ΅ ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π½ΠΎΠΌΠ΅ΡΠ°
}
func (pwd Password) Strength() SecurityLevel {
// ΠΡΠ΅Π½ΠΊΠ° Π½Π°Π΄Π΅ΠΆΠ½ΠΎΡΡΠΈ ΠΏΠ°ΡΠΎΠ»Ρ
}
ΠΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π° ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π°
Fail Fast ΠΏΡΠΈΠ½ΡΠΈΠΏ: ΠΡΠΈΠ±ΠΊΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°ΡΡΡΡ ΠΏΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, Π° Π½Π΅ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ
ΠΠ΅ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΡΡΡ: ΠΠΎΡΠ»Π΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡ Π³Π°ΡΠ°Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎ ΠΊΠΎΡΡΠ΅ΠΊΡΠ΅Π½
Π‘Π°ΠΌΠΎΠ΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅: Π’ΠΈΠΏ ΡΡΠ°Π·Ρ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ ΠΈ ΡΠΎΡΠΌΠ°Ρ Π΄Π°Π½Π½ΡΡ
ΠΠΎΠΌΠΏΠΎΠ·ΠΈΡΠΈΡ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΉ: ΠΠΎΠΆΠ½ΠΎ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠΎΠ²Π°ΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΠΈΠΏΡ ΠΏΡΠΎΠ²Π΅ΡΠΎΠΊ
π Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ²
package main
import (
"fmt"
"strconv"
)
// ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π΄Π»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΡΠ°Π²Π½ΠΈΠ²Π°ΡΡ
type Comparable interface {
Compare(other Comparable) int
}
// Version ΡΠΈΠΏ Π΄Π»Ρ Π²Π΅ΡΡΠΈΠΉ ΠΠ
type Version struct {
Major, Minor, Patch int
}
func (v Version) String() string {
return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
}
func (v Version) Compare(other Comparable) int {
otherVersion, ok := other.(Version)
if !ok {
return -1
}
if v.Major != otherVersion.Major {
return v.Major - otherVersion.Major
}
if v.Minor != otherVersion.Minor {
return v.Minor - otherVersion.Minor
}
return v.Patch - otherVersion.Patch
}
// Score ΡΠΈΠΏ Π΄Π»Ρ ΠΈΠ³ΡΠΎΠ²ΠΎΠ³ΠΎ ΡΡΠ΅ΡΠ°
type Score int
func (s Score) String() string {
return strconv.Itoa(int(s))
}
func (s Score) Compare(other Comparable) int {
otherScore, ok := other.(Score)
if !ok {
return -1
}
return int(s - otherScore)
}
func CompareItems(a, b Comparable) string {
result := a.Compare(b)
switch {
case result > 0:
return fmt.Sprintf("%v > %v", a, b)
case result < 0:
return fmt.Sprintf("%v < %v", a, b)
default:
return fmt.Sprintf("%v = %v", a, b)
}
}
func main() {
v1 := Version{1, 2, 3}
v2 := Version{1, 2, 4}
v3 := Version{1, 2, 3}
fmt.Println(CompareItems(v1, v2))
fmt.Println(CompareItems(v1, v3))
score1 := Score(100)
score2 := Score(95)
fmt.Println(CompareItems(score1, score2))
}
π§ ΠΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΏΡΠΈΠΌΠ΅Ρ
Π‘ΠΈΡΡΠ΅ΠΌΠ° ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π·Π°Π΄Π°ΡΠ°ΠΌΠΈ:
package main
import (
"fmt"
"time"
)
type TaskID int
type UserID int
type Priority int
const (
Low Priority = iota
Medium
High
Critical
)
type Status int
const (
Todo Status = iota
InProgress
Done
Archived
)
type Task struct {
ID TaskID
Title string
Description string
AssignedTo UserID
Priority Priority
Status Status
Created time.Time
Updated time.Time
DueDate *time.Time
}
// ΠΠ΅ΡΠΎΠ΄Ρ Π΄Π»Ρ Priority
func (p Priority) String() string {
names := []string{"Low", "Medium", "High", "Critical"}
return names[p]
}
func (p Priority) Color() string {
colors := []string{"π’", "π‘", "π ", "π΄"}
return colors[p]
}
// ΠΠ΅ΡΠΎΠ΄Ρ Π΄Π»Ρ Status
func (s Status) String() string {
names := []string{"Todo", "In Progress", "Done", "Archived"}
return names[s]
}
func (s Status) Icon() string {
icons := []string{"β", "π", "β
", "π¦"}
return icons[s]
}
// ΠΠ΅ΡΠΎΠ΄Ρ Π΄Π»Ρ Task
func (t *Task) SetPriority(p Priority) {
t.Priority = p
t.Updated = time.Now()
}
func (t *Task) SetStatus(s Status) {
t.Status = s
t.Updated = time.Now()
}
func (t *Task) IsOverdue() bool {
if t.DueDate == nil {
return false
}
return time.Now().After(*t.DueDate) && t.Status != Done
}
func (t *Task) String() string {
overdue := ""
if t.IsOverdue() {
overdue = " β οΈ OVERDUE"
}
due := "No due date"
if t.DueDate != nil {
due = t.DueDate.Format("2006-01-02")
}
return fmt.Sprintf("[%d] %s %s\n %s %s | Due: %s%s\n Assigned to: User %d",
t.ID, t.Status.Icon(), t.Title,
t.Priority.Color(), t.Priority,
due, overdue, t.AssignedTo)
}
func main() {
dueDate := time.Now().AddDate(0, 0, -1) // ΠΡΠ΅ΡΠ° (ΠΏΡΠΎΡΡΠΎΡΠ΅Π½ΠΎ)
task := Task{
ID: TaskID(1),
Title: "Implement user authentication",
Description: "Add JWT authentication to the API",
AssignedTo: UserID(123),
Priority: High,
Status: InProgress,
Created: time.Now().AddDate(0, 0, -7),
Updated: time.Now(),
DueDate: &dueDate,
}
fmt.Printf("Task Details:\n%s\n\n", &task)
// ΠΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ
task.SetPriority(Critical)
fmt.Printf("After priority change:\n%s\n\n", &task)
// ΠΠ°Π²Π΅ΡΡΠ°Π΅ΠΌ Π·Π°Π΄Π°ΡΡ
task.SetStatus(Done)
fmt.Printf("After completion:\n%s\n", &task)
}
π§ ΠΡΠΎΠ²Π΅ΡΡ ΡΠ΅Π±Ρ
- ΠΠ°ΠΊ ΡΠΎΠ·Π΄Π°ΡΡ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠΉ ΡΠΈΠΏ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠ΅Π³ΠΎ?
- ΠΠΎΠΆΠ½ΠΎ Π»ΠΈ Π½Π°ΠΏΡΡΠΌΡΡ ΠΏΡΠΈΡΠ²ΠΎΠΈΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΠ°Π·Π½ΡΡ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΡ ΡΠΈΠΏΠΎΠ²?
- ΠΠ°ΠΊ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΊ ΠΊΠ°ΡΡΠΎΠΌΠ½ΠΎΠΌΡ ΡΠΈΠΏΡ?
- Π ΡΠ΅ΠΌ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΡ ΡΠΈΠΏΠΎΠ² Π²ΠΌΠ΅ΡΡΠΎ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ ?
- ΠΠ°ΠΊ ΡΠΎΠ·Π΄Π°ΡΡ enum-ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠΉ ΡΠΈΠΏ Π² Go?
π ΠΠ»Π°Π²Π½ΠΎΠ΅ ΠΈΠ· Π³Π»Π°Π²Ρ
- ΠΠ°ΡΡΠΎΠΌΠ½ΡΠ΅ ΡΠΈΠΏΡ ΡΠΎΠ·Π΄Π°ΡΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ
type NewType ExistingType
- ΠΠ΅ΡΠΎΠ΄Ρ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΠΊ Π»ΡΠ±ΡΠΌ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠΌ ΡΠΈΠΏΠ°ΠΌ
- ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ ΡΠΈΠΏΠΎΠ² ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ°Π΅Ρ ΠΎΡΠΈΠ±ΠΊΠΈ Π½Π° ΡΡΠ°ΠΏΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ
- Enum-ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠ΅ ΡΠΈΠΏΡ ΡΠΎΠ·Π΄Π°ΡΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ
const
ΠΈiota
- ΠΠ°Π»ΠΈΠ΄Π°ΡΠΈΡ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π²ΡΡΡΠΎΠ΅Π½Π° Π² ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΡ ΡΠΈΠΏΠΎΠ²
- ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠΌΠΈ ΡΠΈΠΏΠ°ΠΌΠΈ ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΌΠΈ