Stringer 是一個介面,用來定義值的字串格式。
這個介面只包含一個 String 方法:
type Stringer interface {
String() string
}
想要實作這個介面的型別,必須有一個 String() 方法,回傳該型別方便人類閱讀的字串表示。
fmt 套件(以及許多其他套件)會尋找這個方法,用來格式化和印出值。
假設我們正在開發一個應用程式,用來處理以不同單位測量的地理距離。
我們定義了 DistanceUnit 和 Distance 兩個型別,如下所示:
type DistanceUnit int
const (
Kilometer DistanceUnit = 0
Mile DistanceUnit = 1
)
type Distance struct {
number float64
unit DistanceUnit
}
在上面的範例中,Kilometer 和 Mile 是型別為 DistanceUnit 的常數。
這些型別沒有 String 方法,所以並未實作 Stringer 介面。
因此,fmt 的函式會使用 Go 的「預設格式」來印出 Distance 值:
mileUnit := Mile
fmt.Sprint(mileUnit)
// => 1
// The result is '1' because that is the underlying value of the 'Mile' constant (see constant declarations above)
dist := Distance{number: 790.7, unit: Kilometer}
fmt.Sprint(dist)
// => {790.7 0}
// not a very useful output!
為了讓輸出更有意義,我們為 DistanceUnit 和 Distance 型別各加上一個 String 方法,藉此實作 Stringer 介面:
func (sc DistanceUnit) String() string {
units := []string{"km", "mi"}
return units[sc]
}
func (d Distance) String() string {
return fmt.Sprintf("%v %v", d.number, d.unit)
}
fmt 套件的函式在格式化 Distance 值時,會呼叫這些方法:
kmUnit := Kilometer
kmUnit.String()
// => km
mileUnit := Mile
mileUnit.String()
// => mi
dist := Distance{
number: 790.7,
unit: Kilometer,
}
dist.String()
// => 790.7 km
你的團隊正在開發一個氣象應用程式。
他們定義了一組 API,內含各種代表氣象資料的型別與常數,請見meteorology.go檔案。
你的任務是為所有型別加上合適的 String 方法,讓它們實作 Stringer 介面。
TemperatureUnit 型別實作 Stringer 介面經過一番討論,團隊決定溫度的單位採用 Celsius 或 Fahrenheit。
值應如下方範例所示格式化。
請為 TemperatureUnit 型別加上 String 方法,讓它實作 Stringer 介面。
若溫度單位是 Celsius,這個方法必須回傳字串 "°C";若是 Fahrenheit,則必須回傳 "°F"。
celsiusUnit := Celsius
fahrenheitUnit := Fahrenheit
celsiusUnit.String()
// => °C
fahrenheitUnit.String()
// => °F
fmt.Sprint(celsiusUnit)
// Output: °C
Temperature 型別實作 Stringer 介面溫度值由一個整數和一個溫度單位組成。 它們應如下方範例所示格式化。
為了做到這點,請為 Temperature 型別加上 String 方法,讓它實作 Stringer 介面。
這個方法應回傳一個字串,內容是溫度的數值和溫度單位,兩者以空格分隔:<temperature> <unit>:
celsiusTemp := Temperature{
degree: 21,
unit: Celsius,
}
celsiusTemp.String()
// => 21 °C
fmt.Sprint(celsiusTemp)
// Output: 21 °C
fahrenheitTemp := Temperature{
degree: 75,
unit: Fahrenheit,
}
fahrenheitTemp.String()
// => 75 °F
fmt.Sprint(fahrenheitTemp)
// Output: 75 °F
SpeedUnit 型別實作 Stringer 介面經過冗長的討論,團隊決定風速的單位採用 KmPerHour 或 MilesPerHour。
值應如下方範例所示格式化。
為了做到這點,請為 SpeedUnit 型別加上 String 方法,讓它實作 Stringer 介面。
若速度單位是每小時公里,這個方法必須回傳字串 "km/h";若是每小時英里,則必須回傳 "mph":
mphUnit := MilesPerHour
mphUnit.String()
// => mph
fmt.Sprint(mphUnit)
// Output: mph
kmhUnit := KmPerHour
kmhUnit.String()
// => km/h
fmt.Sprint(kmhUnit)
// Output: km/h
Speed 型別實作 Stringer 介面風速值由一個整數和一個速度單位組成。 它們應如下方範例所示格式化。
為了做到這點,請為 Speed 型別加上 String 方法,讓它實作 Stringer 介面。
這個方法應回傳一個字串,內容是速度的數值和速度單位,兩者以空格分隔:<speed> <unit>:
windSpeedNow := Speed{
magnitude: 18,
unit: KmPerHour,
}
windSpeedNow.String()
// => 18 km/h
fmt.Sprintf(windSpeedNow)
// Output: 18 km/h
windSpeedYesterday := Speed{
magnitude: 22,
unit: MilesPerHour,
}
windSpeedYesterday.String()
// => 22 mph
fmt.Sprint(windSpeedYesterday)
// Output: 22 mph
MeteorologyData 型別實作 Stringer 介面氣象資料包含地點、溫度、風向、風速和濕度。 它們應如下方範例所示格式化:
為了做到這點,請為 MeteorologyData 型別加上 String 方法,讓它實作 Stringer 介面。
這個方法應以下列格式回傳氣象資料:
<location>: <temperature>, Wind <wind_direction> at <wind_speed>, <humidity>% Humidity
sfData := MeteorologyData{
location: "San Francisco",
temperature: Temperature{
degree: 57,
unit: Fahrenheit
},
windDirection: "NW",
windSpeed: Speed{
magnitude: 19,
unit: MilesPerHour
},
humidity: 60
}
sfData.String()
// => San Francisco: 57 °F, Wind NW at 19 mph, 60% Humidity
fmt.Sprint(sfData)
// Output: San Francisco: 57 °F, Wind NW at 19 mph, 60% Humidity