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 هستند.
این نوعها اینترفیس Stringer را پیادهسازی نمیکنند، چون متد String را ندارند.
در نتیجه، توابع fmt مقادیر Distance را با «قالب پیشفرض» Go چاپ میکنند:
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!
برای اینکه خروجی اطلاعات بیشتری بدهد، اینترفیس Stringer را برای نوعهای DistanceUnit و Distance پیادهسازی میکنیم و به هر نوع یک متد String اضافه میکنیم:
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 را پیادهسازی کنند.
Stringer برای نوع TemperatureUnit
بعد از کمی بحث، تیم توافق کرده است که یکای دما یا Celsius خواهد بود یا Fahrenheit.
مقادیر باید همانطور که در مثالهای زیر نشان داده شده قالببندی شوند.
نوع TemperatureUnit را طوری تغییر دهید که با افزودن یک متد String به آن، رابط Stringer را پیادهسازی کند.
این متد باید رشتهی "°C" را برگرداند اگر یکای دما سلسیوس است، و "°F" را اگر یکای دما فارنهایت است.
celsiusUnit := Celsius
fahrenheitUnit := Fahrenheit
celsiusUnit.String()
// => °C
fahrenheitUnit.String()
// => °F
fmt.Sprint(celsiusUnit)
// Output: °C
Stringer برای نوع Temperature
مقادیر دما از یک عدد صحیح و یک یکای دما تشکیل شدهاند. باید همانند مثالهای زیر قالببندی شوند.
برای این کار، نوع 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
Stringer برای نوع SpeedUnit
بعد از بحثهای طولانی، تیم توافق کرده است که یکای سرعت باد یا 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
Stringer برای Speed
مقادیر سرعت باد از یک عدد صحیح و یک یکای سرعت تشکیل شدهاند. باید همانند مثال زیر قالببندی شوند.
برای این کار، نوع 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
Stringer برای نوع MeteorologyData
دادههای هواشناسی مکان، دما، جهت باد، سرعت باد و رطوبت را مشخص میکند. باید همانند مثال زیر قالببندی شود:
برای این کار، نوع 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