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 يُنفّذ الواجهة Stringer بإضافة طريقة String إليه.
يجب أن تُرجع هذه الطريقة السلسلة النصية "°C" إذا كانت وحدة الحرارة Celsius أو "°F" إذا كانت وحدة الحرارة Fahrenheit.
celsiusUnit := Celsius
fahrenheitUnit := Fahrenheit
celsiusUnit.String()
// => °C
fahrenheitUnit.String()
// => °F
fmt.Sprint(celsiusUnit)
// Output: °C
Stringer للنوع Temperature
تتكون قيم Temperature من عدد صحيح ووحدة حرارة.
ينبغي تنسيقها كما في الأمثلة أدناه.
لتحقيق ذلك، اجعل النوع Temperature يُنفّذ الواجهة Stringer بإضافة طريقة String إليه.
ينبغي أن تُرجع هذه الطريقة سلسلة نصية تحتوي على القيمة العددية للحرارة ووحدة الحرارة مفصولتين بمسافة: <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 يُنفّذ الواجهة Stringer بإضافة طريقة String إليه.
يجب أن تُرجع هذه الطريقة السلسلة النصية "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 يُنفّذ الواجهة Stringer بإضافة طريقة String إليه.
ينبغي أن تُرجع هذه الطريقة سلسلة نصية تحتوي على القيمة العددية للسرعة ووحدة السرعة مفصولتين بمسافة: <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 يُنفّذ الواجهة Stringer بإضافة طريقة String إليه.
ينبغي أن تُرجع هذه الطريقة بيانات الأرصاد الجوية بالتنسيق التالي:
<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
سجّل في Exercism لتتعلّم وتتقن Go عبر 34 مفهومًا166 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.