# تکرار

[**شما می‌توانید کدهای این بخش را اینجا ببینید**](https://github.com/quii/learn-go-with-tests/tree/main/for)

برای انجام کارهای تکراری در گو شما از `for` استفاده می‌کنید، در گو عبارات کلیدی `while`، `do`، و `until` وجود ندارد. تنها ابزار شما `for` می‌باشد که چیز خوبیست.

بیایید تابعی بنویسیم که یک حرف را پنج بار تکرار می‌کند.

چیز جدیدی در ایت زمینه وجود ندارد پس تلاش کنید خودتان بنویسید.

## ابتدا تست را می‌نویسیم

```go
package iteration

import "testing"

func TestRepeat(t *testing.T) {
	repeated := Repeat("a")
	expected := "aaaaa"

	if repeated != expected {
		t.Errorf("expected %q but got %q", expected, repeated)
	}
}
```

## تلاش می‌کنیم تست را اجرا کنیم

`./repeat_test.go:6:14: undefined: Repeat`

## کمترین میزان کد برای اجرای تست را می‌نویسیم که خطایی که تستمان می‌دهد را ببینیم

مراحل را به ترتیب انجام دهید شما چیز جدیدی لازم نیست بدانید که کاری کنید تست خطا بدهد.

تمام چیزی که لازم هست مقدار کافی کد هست که باعث کامپایل شدن تست بشود اما باعث پاس شدن آن نشود.

```go
package iteration

func Repeat(character string) string {
	return ""
}
```

خوب نیست که می‌دانید برای مسائل پایه‌ای چگونه تست گو بنویسید؟ این یعنی شما حالا می‌توانیدهرچقدر که می‌خواهید با پروداکشن کار کنید و خیالتان راحت باشد که همه چیز درست است یا نه.

`repeat_test.go:10: expected 'aaaaa' but got ''`

## به اندازه‌ی کافی کد بنویسید که پاس شود

سینتکس `for` به شدت شبیه زبان سی می‌باشد و چیز زیادی ندارد.

```go
func Repeat(character string) string {
	var repeated string
	for i := 0; i < 5; i++ {
		repeated = repeated + character
	}
	return repeated
}
```

برخلاف زبان‌های دیگر همچون سی، جاوا، و جاوااسکریپت، برای حلقه‌ نیازی به پرانتز نیست و گذاشتن کرلی براکت `{}` الزامی هست. شاید برایتان سوال باشد که خط پایین یعنی چه

```go
	var repeated string
```

قبلا ما برای ساخت یک متغیر از `:=` استفاده می‌کردیم که ابزاری برای ساختن و مقداردهی به یک متغیر بود و [دو کار را با هم انجام می‌داد](https://gobyexample.com/variables). در خط بالا ما تنها متغیر را می‌سازیم و به آن مقدار نمی‌دهیم. از `var` برای ساخت تابع هم می‌توان استفاده کرد که بعدا می‌بینیم.

تست را اجرا کنید الان باید پاس شود.

روش استفاده از for به شکل مفصل [اینجا](https://gobyexample.com/for) توضیح داده شده.

## ری‌فکتور

حالا زمان ری‌فکتور و معرفی یک اپراتور جدید است، `=+` .

```go
const repeatCount = 5

func Repeat(character string) string {
	var repeated string
	for i := 0; i < repeatCount; i++ {
		repeated += character
	}
	return repeated
}
```

`=+` که متغیر اضافه کردن و مقداردهی است. کار آن این است که مقدار سمت راست اپراتور را با مقدار سمت چپ جمع کند و پاسخ را در متغیر سمت چپ بریزد. این با انواع دیگری همچون اعداد صحیح هم کار می‌کند.

### بنچمارک

نوشتن [بنچمارک](https://golang.org/pkg/testing/#hdr-Benchmarks) یکی دیگر از ویژگی‌های مهم گو هست و همچون تست نوشتن می‌ماند.

```go
func BenchmarkRepeat(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Repeat("a")
	}
}
```

همانطور که می‌بینید بنچمارک‌نویسی مثل تست‌نویسی می‌ماند.

عبارت `testing.B` به شما این امکان را می‌دهد که از `b.N` استفاده کنید.

وقتی بنچمارک اجرا می‌شود, به تعداد `b.N` بار تکرار می‌شود و در آخر محاسبه می‌کند که چقدر طول کشید.

تعداد دفعات اجرای کد نباید برای شما مهم باشد, خود سرویس برای شما تعداد «مناسب» را برای شما تعیین می‌کند.

برای اجرای بنچمارک دستور زیر را بزنید

`go test -bench=.`

```
goos: darwin
goarch: amd64
pkg: github.com/quii/learn-go-with-tests/for/v4
10000000           136 ns/op
PASS
```

مقدار `136 ns/op` یعنی کد ما به شکل میانگین ۱۳۶ نانو ثانیه طول کشیده تا تابع را اجرا کند که مقدار خوبی مجسوب می‌شود.

نکته: به شکل پیش‌فرض بنچمارک‌ یکی یکی اجرا می‌شود.

## تمرین

* تست را به گونه‌ای تغییر دهید که تست تعداد دفعات تکرار را بگیرد و سپس کد را براساس آن درست کنبد
* یک `ExampleRepeat` بنویسید تا از تابع خود مستند داشته باشید
* نگاهی به بسته‌ی [strings](https://golang.org/pkg/strings) بیندازید. توابعی که فکر می‌کنید مفید باشند را پیدا کنید و با استفاده از آن‌ها تست بنویسید. یادگیری کتابخانه‌ی استاندارد در بلند مدت بسیار مفید است.

## جمع‌بندی

* تمرین تست محور بیشتر
* یادگیری `for`
* یادگیری نوشتن بنچمارک


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://go-yaad-begir.gitbook.io/go-ba-test/aswl-gw/iteration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
