Verse programlama dilinin tüm özellikleri ve sözdizimi hakkında bir hızlı referans kaynağı olarak bu dokümanı kullan. Daha fazla bilgi edinmek için bağlantıları izle.
İfadeler
İfade, hesaplandığında bir değer oluşturan en küçük kod birimidir. Bir örneği if ... else ifadesidir. Verse’te ifade bloklarının içeriğine bağlı bir değer olarak hesaplanır.
Aşağıdaki kod, MyNumber değerinin 5’ten büyük olup olmamasına bağlı olarak “Big!” veya “Small!” değerini içeren bir dizeyi değerlendirir:
if (MyNumber > 5):
"Big!"
else:
"Small!"
Kod Açıklamaları
Kod açıklaması, kodla ilgili bir şeyi veya programcının bir şeyin programlanış biçiminin sebebini açıklamasını sağlar. Program çalıştığında kod açıklamaları dikkate alınmaz.
Verse | Tek satırlı açıklama: |
Verse | Satır içi blok açıklama: |
Verse | Çok satırlı blok açıklama: |
Verse | İç içe yerleştirilmiş blok açıklama: |
Verse | Girintili açıklama: |
Sabitler ve Değişkenler
Sabitler ve değişkenler, programının kullandığı bilgileri ya da değerleri depolayabilir ve bu değerleri bir adla ilişkilendirebilir. Ad tanımlayıcıdır.
Kendi değişkenini veya sabitini oluşturmak için Verse’e bunu söylemen gerekir. Buna bildirim denir. Başlatma adı verilen bir başlangıç değeri belirtmek, değişkenler için isteğe bağlı (ancak önerilen), sabitler içinse zorunlu bir eylemdir.
Bir değişkenin değerini istediğin zaman değiştirebilirsin. Değişkene bir değer atadığın için bu kavram atama olarak adlandırılır ancak bazı durumlarda değişkeni ayarlama olarak da anılır.
Verse | Sabit oluşturma: Bir sabitin değeri program çalışırken değiştirilemez. Adını, türünü ve değerini belirterek bir sabit oluşturabilirsin. | Büyütmek için görsele tıkla. |
Verse | Değişken oluşturma: Bir değişkenin değeri program çalışırken değiştirilebilir. Bir değişkeni, adının önüne | Büyütmek için görsele tıkla. |
Verse | Değişkenin değerini değiştirme: Program çalışırken | Büyütmek için görsele tıkla. |
Türler
Verse statik türde bir programlama dilidir, yani her tanımlayıcıya bir tür atanır.
Bir fonksiyonda sabit oluştururken olduğu gibi türün açıkça gerekli olmadığı örnekler vardır. MyConstant := 0 örneğinde MyConstant için atanan değer 0 olduğundan türü çıkarsanır.
Yaygın Türler
Verse çoğu programın çalışmak için ihtiyaç duyduğu temel işlemleri destekleyen yerleşik türlere sahiptir. Bunları daha büyük yapılar halinde birleştirerek kendi türlerini oluşturabilirsin ancak Verse’te değişken ve sabitleri kullanmanın temeli olarak yaygın türleri anlamak önemlidir.
Verse | logic: Verse’te |
Verse | int: Verse’te
|
Verse | float: Verse’te
|
Verse | string: Verse’te Bir ifadenin sonucunu, "" içinde {} kullanarak bir dizeye ekleyebilirsin. Buna dize interpolasyonu adı verilir.
|
Verse | message: Verse’te
Şu anda |
Verse | locale: Bu tür, bir Şu anda |
Verse | rational:
|
Verse | void:
|
Verse | any: |
Verse | comparable: |
Verse’teki yaygın türler hakkında daha fazla bilgi almak için Yaygın Türler kısmına bakabilirsin.
Kapsayıcı Türleri
Bir kapsayıcı türü kullanarak birden fazla değeri bir arada saklayabilirsin. Verse, içinde değerlerin depolanabileceği birkaç kapsayıcı türüne sahiptir. Verse’teki kapsayıcı türleri hakkında daha fazla bilgi almak için Kapsayıcı Türleri kısmına bakabilirsin.
Seçenek
option türü bir değer içerebilir veya boş olabilir.
Aşağıdaki örnekte MaybeANumber hiçbir değer içermeyen isteğe bağlı bir ?int tamsayısıdır. Bu durumda MaybeANumber için yeni değer 42 olarak ayarlanır.
var MaybeANumber : ?int = false # unset optional value
set MaybeANumber := option{42} # assigned the value 42
Büyütmek için görsele tıkla.
Verse | Seçenek oluşturma: Bir seçeneği aşağıdakilerden biriyle başlatabilirsin:
Seçenekte depolanması beklenen değer türünün önüne |
Verse | Seçenek içindeki bir elemana erişim: Seçenekle birlikte |
Aşağıda, doğan bir oyuncuya yönelik referansı kaydetmek ve oyuncu doğduğunda tetikleyici cihazın tepki vermesini sağlamak için bir seçenek (option) türünün kullanıldığı bir örnek yer alıyor:
my_device := class<concrete>(creative_device):
var SavedPlayer : ?player = false # unset optional value
@editable
PlayerSpawn : player_spawner_device = player_spawner_device{}
@editable
Trigger : trigger_device = trigger_device{}
OnBegin<override>() : void =
Aralık
range ifadesi, belirtilen bir aralıktaki tüm sayıları içerir ve yalnızca for ifadesi gibi belirli ifadelerde kullanılabilir. Aralık değerleri yalnızca tamsayı olabilir.
Büyütmek için görsele tıkla.
Verse | Aralık oluşturma: Aralığın başlangıcı, ifadedeki ilk değer; aralığın sonu ise ifadede |
Verse | Bir aralıkta yineleme: |
Daha fazla bilgi için Aralık kısmına bakabilirsin.
Dizi
Dizi, aynı türden elemanları depolayabileceğin bir kapsayıcıdır. Dizide elemanlara konumlarına göre erişebilirsin. Bu konuma dizin adı verilir. Bir dizideki ilk dizin 0, son dizin dizideki öğe sayısının bir eksiğidir.
Players : []player = array{Player1, Player2}
Büyütmek için görsele tıkla.
Verse | Dizi oluşturma: |
Verse | Dizideki bir elemana erişme: Erişmek istediğin elemanın diziniyle birlikte |
Verse | Dizideki bir elemanı değiştirme: Bir dizindeki dizi değişkeninde depolanmış değeri |
Verse | Bir dizide yineleme: Bir dizideki her elemana birinciden sonuncuya giden sırayla for ifadesi kullanarak erişebilirsin. |
Verse | Dizideki eleman sayısını alma: Dizide |
Verse | Dizileri birleştirme: |
Daha fazla bilgi için Dizi kısmına bak.
demet
Demet, tek bir ifade olarak ele alınan iki veya daha fazla ifadenin gruplandırılmış halidir. İfadedeki öğelerin sırası önemlidir. Aynı ifade, bir demetin birden fazla konumunda olabilir. Demet ifadeleri herhangi bir türde olabilir ve (yalnızca bir türden eleman içerebilen dizilerin aksine) karışık türlere sahip olabilir.
Demetler özellikle aşağıdaki durumlarda faydalıdır:
Bir fonksiyondan birden fazla değer döndürürken.
Bir fonksiyona birden fazla değer geçirirken.
Yerinde gruplandırma, yeniden kullanılabilir bir veri yapısı (bir struct veya class gibi) oluşturma ek yüküne göre daha kestirme bir yoldur.
VerseExampleTuple : tuple(int, float, string) = (1, 2.0, "three")
Büyütmek için görsele tıkla.
Verse | Demet oluşturma: |
Demetteki bir elemana erişme: Erişmek istediğin elemanın diziniyle birlikte | |
Demet genişlemesi: Her bağımsız değişkeni belirtmek yerine bir demeti bir fonksiyonun bağımsız değişkeni olarak kullandığında; fonksiyon, bağımsız değişken olarak kullanılan demetteki her bir eleman ile birlikte öğelerin demette belirtildikleri sırayla çağrılır. | |
Demet dizisini zorlama: Demetler, demet elemanlarının türleri dizi ile aynı türde olmak şartıyla bir dizinin beklendiği her durumda geçirilebilir. Bir demetin beklendiği durumlarda diziler geçirilemez. |
Daha fazla bilgi için Demet kısmına bakabilirsin.
Harita
Harita, anahtar-değer çifti adı verilen başka bir değerle ilişkili değerleri depolayabileceğin ve öğelere benzersiz anahtarlarına göre erişebileceğin bir kapsayıcıdır.
WordCount : [string]int = map {"apple" => 11, "pear" => 7}
Büyütmek için görsele tıkla.
Harita oluşturma: | |
Haritadaki bir elemana erişme: Erişmek istediğin elemanın anahtarıyla birlikte | |
Harita üzerinde yineleme: Bir haritadaki her elemana birinciden sonuncuya giden sırayla for ifadesi kullanarak erişebilirsin. | |
Haritadaki anahtar-değer çiftlerinin sayısını alma: Haritada |
Daha fazla bilgi için Harita kısmına bakabilirsin.
Kompozit Türler
Kompozit tür, primitif veya diğer türlerin alan ve elemanlarından (genellikle adlandırılmış) oluşabilen herhangi bir türdür. Bileşik türler ömrü boyunca genellikle sabit sayıda alana veya öğeye sahiptir. Daha fazla bilgi Kompozit Türler kısmına bakabilirsin.
Enum
Enum, enumerator (numaralandırıcı) adı verilen ve bir dizi şeyi adlandırmak veya listelemek anlamına gelen enumeration (numaralandırma) sözcüğünün kısaltmasıdır. Enum, Verse’te haftanın günleri veya pusula yönleri gibi şeyler için kullanılabilen bir türdür.
Büyütmek için görsele tıkla.
Enum oluşturma: | |
Numaralandırıcıya erişim: Enum üzerinde |
Yapı
Yapı (İngilizce karşılığı olan struct, structure’ın kısaltmasıdır), birbiriyle ilgili birkaç değişkeni birlikte gruplandırmanın bir yoludur. Değişkenler herhangi bir türden olabilir.
Büyütmek için görsele tıkla.
Büyütmek için görsele tıkla.
Yapı oluşturma: | |
Yapı örneği oluşturma: Bir arketipten yapı örneği oluşturabilirsin. Arketip, bir yapının alanlarının değerlerini tanımlar. | |
Bir yapıdaki alanlara erişme: Bir yapının alanlarına erişebilir ve yapı örneği ile alan adı arasına |
Sınıf
Sınıf, benzer davranış ve özelliklere (değişken ve metotlar) sahip objeler oluşturmaya yönelik bir şablondur; gerçek değerlere sahip bir obje oluşturmak için sınıfın örneği oluşturulmalıdır. Sınıflar hiyerarşiktir, yani bir sınıf, üstünden (üst sınıfından) devralabilir ve bilgilerini altları (alt sınıfları) ile paylaşabilir. Sınıf, kullanıcı tarafından tanımlanan özel bir tür olabilir.
Büyütmek için görsele tıkla.
Büyütmek için görsele tıkla.
Sınıf oluşturma: Bir sınıfın içinde iç içe geçmiş tanımlar, sınıfın alanlarını tanımlamaktadır. Bir sınıfın alanları olarak tanımlanan fonksiyonlar metot olarak da anılır. | |
Sınıf örneği oluşturma: Sınıf adı ve ardından | |
Bir sınıftaki alanlara erişme: Bir yapının alanlarına erişebilir ve sınıf örneği ile alan adı arasına | |
Bir sınıftaki metotlara erişme: Bir sınıfın metotlarına erişebilir ve sınıf örneği ile metot adı arasında | |
Self: |
Ayrıca sınıflara özel olan ve davranışlarını değiştirebilen belirleyiciler vardır. Ayrıntılar için Sınıf Belirleyicileri kısmına bak.
Sınıflar hakkında daha fazla bilgi almak için Sınıf kısmına bakabilirsin.
Alt Sınıf
Alt sınıf; diğer bir sınıfın (üst sınıf adı verilir) tanımını genişleten bir sınıftır. Bu genişletme işlemi, diğer sınıfa alan ve metotlar ekleyerek veya bu sınıfın alan ve metotlarını değiştirerek gerçekleşir.
Büyütmek için görsele tıkla.
Alt sınıf oluşturma: | |
Üst sınıftaki alanları geçersiz kılma: Yalnızca alan adına | |
Üst sınıftaki metotları geçersiz kılma: [INCLUDE:#overriding_methods_on_superclass_description] | |
Super: |
Daha fazla bilgi için Alt Sınıf kısmına bakabilirsin.
Oluşturucu
Oluşturucu, ilişkili olduğu sınıfın bir örneğini oluşturan özel bir fonksiyondur. Yeni objenin başlangıç değerlerini belirlemek için kullanılabilir.
Sınıf için oluşturucu tanımlama: Fonksiyon adına | |
Oluşturucuda değişken ekleme ve kod yürütme: Bir block ifadesiyle oluşturucu içinde ifadeleri yürütebilir, | |
Bir oluşturucuda diğer oluşturucuları çağırma: Bir oluşturucudan diğer oluşturucuları çağırabilirsin. Tüm alanlar başlatıldığı sürece, sınıfın üst sınıfı için oluşturucuları sınıfın bir oluşturucusundan da çağırabilirsin. Bir oluşturucu başka bir oluşturucuyu çağırdığında ve her iki oluşturucu da alanları başlattığında, alanlar için yalnızca ilk oluşturucuya sağlanan değerler kullanılır. İki oluşturucu arasındaki ifadeler için değerlendirme sırası, ifadelerin yazıldığı sırayla aynı olur (yan etkiler bakımından) ancak yalnızca ilk oluşturucuya sağlanan değerler kullanılır. |
Arayüz
Arayüz türü, arayüzü uygulayan herhangi bir sınıfla nasıl etkileşime girileceğine yönelik bir sözleşme sağlar. Bir arayüzün örneği oluşturulamaz ancak bir sınıf, arayüzden devralabilir ve onun yöntemlerini uygulayabilir. Arayüz, tanım kapsamında kısmen uygulamaya veya alanlara izin vermemesi dışında soyut sınıf ile benzerdir.
Büyütmek için görsele tıkla.
Büyütmek için görsele tıkla.
Arayüz oluşturma: Bir arayüzü, bir sınıf tanımlamaya benzer şekilde tanımlayabilirsin. Burada tek fark | |
Bir arayüzü genişletme: Bir arayüz, | |
Bir arayüzü uygulama: Bir arayüzü, | |
Birden fazla arayüz uygulama: Bir sınıf birden fazla arayüz uygulayabilir. Arayüzler | |
Bir arayüzden ve başka bir sınıftan devralma: Bir sınıf, bir arayüzü uygulayabilir ve başka bir sınıfın alt sınıfı olabilir. Arayüz ve üst sınıf, |
Daha fazla bilgi için Arayüz kısmına bakabilirsin.
Türlerle Çalışma
Verse, türlerle çalışmayı kolaylaştıran birkaç yol sunar.
Tür diğer adı: Kodunda bir türe farklı bir ad verebilir ve türü o yeni adla referans alabilirsin. Sözdizimi, sabit başlatma ile benzerdir. Bir fonksiyon türüne de tür diğer adı verebilirsin. Daha fazla bilgi için Tür Diğer Adı kısmına bakabilirsin. | |
Açık tür bağımsız değişkenleri olarak parametrik tür: Verse, parametrik türleri (bağımsız değişken olarak beklenen türler) destekler. Bu özellik yalnızca sınıflar ve fonksiyonlar ile çalışır. Daha fazla bilgi için Parametrik Türler kısmına bakabilirsin. | |
Fonksiyonların örtük tür bağımsız değişkenleri olarak parametrik tür: Örtük parametrik türleri fonksiyonlarla birlikte kullanmanın nedeni, kodu fonksiyonun birlikte kullanıldığı her bir tür için yazmak yerine belirli bir tür için değişmez nitelikte kod yazmana olanak tanımasıdır. Daha fazla bilgi için Parametrik Türler kısmına bakabilirsin. | |
Tür makrosu: Verse rastgele bir ifadenin türünü almak için kullanılabilen özel bir yapıya sahiptir. Bu yapı, türün kullanılabildiği her yerde kullanılabilir. Daha fazla bilgi için Tür Makrosu kısmına bakabilirsin. | |
subtype: |
Daha fazla bilgi için Verse Türleri ile çalışma kısmına bakabilirsin.
İşleçler
İşleçler, Verse programlama dilinde tanımlanan ve işlenenleri üzerinde matematik işlemleri gibi eylemler gerçekleştiren özel işlevlerdir.
Aynı ifadede birden fazla işleç kullanıldığında en yüksekten en düşük önceliğe giden sırayla değerlendirilirler. Aynı ifadede aynı önceliğe sahip işleçler varsa soldan sağa değerlendirilirler.
Aşağıdaki tabloda Verse’teki tüm yerleşik işleçler en yüksekten en düşük önem sırasına göre listeleniyor.
| İşleç | Açıklama | İşleç Formatı | işleç önceliği | Örnek |
|---|---|---|---|---|
|
| sonek | 9 |
|
|
| Önek | 8 |
|
Pozitif |
| Önek | 8 |
|
Negatif |
| Önek | 8 |
|
Çarpma |
| içtakı | 7 |
|
Bölme |
| içtakı | 7 |
|
Toplama | + işleci iki sayı değerini birbiriyle toplar. Dizeler ve dizilerle birlikte kullanıldığında iki değer birleştirilir. Daha ayrıntılı bilgi için Matematik kısmına bakabilirsin. | içtakı | 6 |
|
Çıkarma |
| içtakı | 6 |
|
Toplama atama | Bu işleçle toplama ve atamayı aynı işlemde kullanarak bir değişkenin değerini güncelleyebilirsin. Daha ayrıntılı bilgi için Matematik kısmına bakabilirsin. | içtakı | 5 |
|
Çıkarma atama | Bu işleçle çıkarma ve atamayı aynı işlemde kullanarak bir değişkenin değerini güncelleyebilirsin. Daha ayrıntılı bilgi için Matematik kısmına bakabilirsin. | içtakı | 5 |
|
Çarpma atama | Bu işleçle çarpma ve atamayı aynı işlemde kullanarak bir değişkenin değerini güncelleyebilirsin. Daha ayrıntılı bilgi için Matematik kısmına bakabilirsin. | içtakı | 5 |
|
Bölme atama | Bu işleçle bölme ve atamayı aynı işlemde kullanarak bir tamsayı olan değişkenin değerini güncelleyebilirsin. Daha ayrıntılı bilgi için Matematik kısmına bakabilirsin. | içtakı | 5 |
|
Eşittir |
| içtakı | 4 |
|
Eşit değil |
| içtakı | 4 |
|
Küçüktür |
| içtakı | 4 |
|
Küçük veya eşittir |
| içtakı | 4 |
|
Büyüktür |
| içtakı | 4 |
|
Büyük veya eşittir |
| içtakı | 4 |
|
Ve |
| içtakı | 3 |
|
Veya |
| içtakı | 2 |
|
Değişken ve sabit başlatma | Bu işleçle değerleri bir sabit veya değişkende depolayabilirsin. Daha fazla bilgi için Sabitler ve Değişkenler kısmına bakabilirsin. | içtakı | 1 |
|
Değişken atama | Bu işleçle bir değişkende depolanmış değerleri güncelleyebilirsin. Daha fazla bilgi için Sabitler ve Değişkenler kısmına bakabilirsin. | içtakı | 1 |
|
Daha fazla bilgi için İşleçler kısmına bakabilirsin.
Gruplandırma
İfadeleri () ile gruplandırarak işleçlerin değerlendirildiği sırayı değiştirebilirsin. Örneğin, (1+2)*3 ve 1+(2*3) aynı şekilde değerlendirilmez çünkü ilk olarak () içinde gruplandırılan ifadeler değerlendirilir.
Aşağıdaki örnekte, verdiği hasarı oyuncudan uzaklığa göre ölçeklendiren ancak oyuncu zırhının toplam hasarı azaltabileceği bir oyun içi patlamayı hesaplamak için gruplandırmanın nasıl kullanılacağı gösteriliyor:
BaseDamage : float = 100.0
Armor : float = 15.0
DistanceScaling : float = Max(1.0, Pow(PlayerDistance, 2.0))
ExplosionDamage : float = Max(0.0, (BaseDamage / DistanceScaling) - Armor)
Daha ayrıntılı bilgi için Gruplandırma kısmına bakabilirsin.
Kod blokları
Kod bloku sıfır veya daha fazla ifadeden oluşan bir gruptur ve kapsama alınmış yeni bir gövde ekler. Kod bloğu bir tanımlayıcıyı takip etmelidir. Bu bir fonksiyon tanımlayıcısı veya if ve for gibi bir denetim akışı tanımlayıcısı olabilir.
Aralıklı: | |
Çok satırlı ayraç içine alınmış: Her ifade yeni bir satırda olacak şekilde | |
Tek satırlı ayraç içine alınmış: Her ifade ile birbirinden |
Ayrıca ; kullanarak bir satıra birden fazla ifade yerleştirmek de mümkündür. Her ifadenin yeni bir satırda olduğu bir formatta {} karakterlerinin kendi satırlarında olmaları gerekmez.
Bir kod bloğundaki son ifade, kod bloğunun sonucudur. Aşağıdaki örnekte IsLightOn? başarılı olursa if ifadesi kod bloku false, IsLightOn? başarısız olursa true olur. Bundan sonra logic sonucu NewLightState içinde depolanır.
NewLightState :=
if (IsLightOn?):
Light.TurnOff()
false
else:
Light.TurnOn()
true
Daha fazla bilgi için Kod Blokları kısmına bakabilirsin.
Kapsam
Kapsam bir Verse programında bir tanımlayıcının (ad) bir değer ile ilişkisinin geçerli olduğu ve söz konusu tanımlayıcının değere başvurmak için kullanılabildiği kodu ifade eder.
Örneğin, bir kod bloğu içinde oluşturduğun herhangi bir sabit veya değişken yalnızca o kod bloğunun bağlamında mevcut olur. Buna göre, objelerin yaşam süresi, oluşturuldukları kapsamla sınırlı olur ve bu objeler bu kod bloğunun dışında kullanılamaz.
Aşağıdaki örnekte oyuncunun sahip olduğu para sayısı kullanılarak satın alınabilecek en fazla ok sayısının nasıl hesaplanacağı gösteriliyor. MaxArrowsYouCanBuy sabiti if bloku içinde oluşturulduğu için kapsam if bloku ile sınırlıdır. MaxArrowsYouCanBuy sabiti yazdırma dizesinde kullanıldığında MaxArrowsYouCanBuy adı söz konusu if ifadesinin dışındaki kapsamda mevcut olmadığından bir hata oluşturur.
CoinsPerQuiver : int = 100
ArrowsPerQuiver : int = 15
var Coins : int = 225
if (MaxQuiversYouCanBuy : int = Floor(Coins / CoinsPerQuiver)):
MaxArrowsYouCanBuy : int = MaxQuiversYouCanBuy * ArrowsPerQuiver
Print("You can buy at most {MaxArrowsYouCanBuy} arrows with your coins.") # Error: Unknown identifier MaxArrowsYouCanBuy
Büyütmek için görsele tıkla.
Verse farklı bir kapsamda bildirilmiş olsa da bir tanımlayıcıyı yeniden kullanmayı desteklemez. Bunun istisnası, tanımlayıcının önüne (qualifying_scope:) ekleyerek tanımlayıcıyı uygun hale getirmektir. Burada qualifying_scope; tanımlayıcının modül, sınıf veya arayüzünün adıdır. Tanımlayıcıyı tanımlayıp kullandığın durumlarda niteleyiciyi de tanımlayıcıya eklemen gerekir.
Fonksiyonlar
Fonksiyon, yeniden kullanabileceğin ifadelerin adlandırılmış sekansıdır. Fonksiyon bir eylemin gerçekleştirilmesi veya bir girdiye dayalı bir çıktı oluşturulması için talimatlar sağlayan yeniden kullanılabilir koddur.
Fonksiyon Tanımları
Kendi fonksiyonunu tanımlamak için üç önemli kısmı sağlamak gerekir: bir benzersiz ad (tanımlayıcı), sonucu olarak bekleyebileceğin bilgi türü ve çağırdığında fonksiyonun yapacakları. Bir fonksiyonun temel sözdizimi aşağıdaki gibidir:
name() : type =
codeblock
İki noktayla ayrılmış name() ve tür: Fonksiyonu nasıl çağırman ve kullanman gerektiğini belirleyen fonksiyon imzasıdır ve fonksiyonun döndürmesi gereken değer burada belirttiğin türde olur. Bu biçim, kodunda fonksiyonu nasıl çağırdığını taklit eden ve addan sonra gelen () dışında, sabitleri oluşturma şekline benzer.
Fonksiyon kod bloku: Fonksiyonun çağrıldığında ne yapacağını,
=codeblockdeğerini belirterek tanımlarsın. Buradacodeblock, bir veya daha fazla ifadeden oluşan bir sekanstır. Fonksiyonu her çağırdığında kod bloğu içindeki ifadeler yürütülür.
Büyütmek için görsele tıkla.
Fonksiyon Sonuçları
Fonksiyonun için belirtilen bir dönüş türü olduğunda fonksiyon gövdesi o türden bir sonuç üretmelidir. Aksi takdirde kod derlenmez.
Bir değerle döndürülen son ifade: Varsayılan olarak, fonksiyonun kod blokundaki son ifade fonksiyonun sonucudur ve değeri fonksiyonun dönüş türü ile eşleşmelidir. | |
Bir değerle açık dönüş: |
Sonuç üretmesi gerekmeyen bir fonksiyon oluşturduğunda fonksiyonun dönüş türünü void olarak ayarlayabilirsin. Bunun anlamı, fonksiyonun faydalı bir sonuç üretmesinin beklenmemesidir ve bu yüzden fonksiyonun kod bloku herhangi bir türde olabilir.
return ifadesini tek başına kullanarak dönüş türü void olan bir fonksiyondan çıkabilirsin. Bu ifade, kod bloğunda kendisinden sonra daha fazla ifade olsa bile fonksiyondan hemen çıkış yapar.
Fonksiyon Parametreleri
Bir fonksiyonun girdisi, parametreler kullanılarak tanımlanır. Parametre, daha sonra fonksiyonun gövdesinde kullanabileceğin, parantez içindeki fonksiyon imzasında bildirilen bir sabittir.
İki parametreli bir fonksiyonun sözdizimi aşağıdaki gibidir:
name(parameter1name : type, parameter2name : type) : type =
codeblock
Büyütmek için görsele tıkla.
Aşağıdaki örnekte IncreaseScore() fonksiyonu, fonksiyonun MyScore değerini artırmak için kullandığı Points adlı bir tamsayı parametresine sahiptir:
var MyScore : int = 100
IncreaseScore(Points : int) : void =
# Increase MyScore by Points.
set MyScore = MyScore + Points
Fonksiyon Çağrıları
Kodunda adlandırılmış ifade sıralamasını (fonksiyon) kullanmak istediğinde fonksiyonu, 1 ile 10’u da kapsayan aralıkta rastgele bir tamsayı döndüren GetRandomInt(1, 10) gibi, bir adla çağırman gerekir.
Fonksiyon çağrısının başarısız olabilir özellikte olup olmamasına bağlı olarak bir fonksiyonu çağırmanın iki yolu vardır:
Başarısız olamaz fonksiyon çağrısı: Başarısız olamaz bir fonksiyon çağrısı | |
Başarısız olabilir fonksiyon çağrısı: Başarısız olabilir bir fonksiyon çağrısı |
Fonksiyon Bağımsız Değişkenleri
Parametreleri bekleyen bir fonksiyon çağırdığında tıpkı sabitleri kullanabilmek için onlara değer atamanın gerekli olması gibi parametrelere değerler ataman gerekir. Atanan değerler, fonksiyonun bağımsız değişkenleri olarak adlandırılır.
İki bağımsız değişkenli bir fonksiyonu çağırmanın sözdizimi aşağıdaki gibidir:
name(parameter1name := value, parameter2name := value)
Aşağıdaki örnekte IncreaseScore() fonksiyonu, MyScore değerini artırmak için her defasında farklı bağımsız değişkenlerle (10, 5 ve 20) olacak şekilde üç kez çağrılır.
# After this call, MyScore is 110
IncreaseScore(Points := 10)
# After this call, MyScore is 115
IncreaseScore(Points := 5)
# After this call, MyScore is 135
IncreaseScore(Points := 20)
Uzantı Metotları
Genişletme metotları, var olan bir sınıfın veya türün üyeleri gibi hareket eden ancak yeni bir tür veya alt sınıf oluşturulmasını gerektirmeyen bir fonksiyon türüdür.
int türündeki diziler için uzantı metodunun nasıl oluşturulacağı aşağıda gösterilmektedir. Yöntem, dizideki tüm sayıları toplar ve toplamı döndürür.
# Sum extension method for type []int
(Arr : []int).Sum<public>() : int =
var Total : int = 0
for (Number : Arr):
set Total = Total + Number
return TotalMetot daha sonra int türündeki herhangi bir dizide çağrılabilir.
SumTotal := array{4, 3, 7}.Sum()
Print("The SumTotal is { SumTotal }")
# "The SumTotal is 14"
Hata
Bir programın akışını değiştirmek için true ve false Boole değerlerini kullanan diğer programlama dillerinin aksine, Verse başarılı veya başarısız olabilen ifadeler kullanır. Bu ifadeler başarısız olabilir ifadeler olarak adlandırılır ve yalnızca bir başarısızlık bağlamında yürütülebilir.
Başarısız Olabilir İfadeler
Başarısız olabilir bir ifade, başarılı olup bir değer üreten veya başarısız olup değer üretmeyen bir ifadedir.
Aşağıdaki liste Verse’teki tüm başarısız olabilir ifadeleri içerir:
Fonksiyon çağrıları: Yalnızca fonksiyon çağrısı | |
Karşılaştırma: Bir karşılaştırma ifadesi, karşılaştırma işleçlerinden birini kullanarak iki şeyi karşılaştırır. Daha fazla bilgi için işleçler kısmına bakabilirsin. | |
Tamsayı bölme: Tamsayılar için | |
Karar: Karar ifadesi, başarı ve başarısızlık karar akışını kontrol edebilmeni sağlayan | |
Sorgu: Sorgu ifadesi | |
Dizideki bir elemana erişme: Dizinde bir eleman olmayabileceğinden ilgili dizide depolanmış değere erişmek başarısız olabilir ifadedir ve bu nedenle bir başarısızlık bağlamında kullanılmalıdır. Daha ayrıntılı bilgi için dizi kısmına bakabilirsin. |
Başarısızlık Bağlamları
Hata bağlamı, başarısız olabilir ifadelerin yürütülmesine izin verilen bir bağlamdır. Bağlam, ifadenin başarısız olması durumunda ne olacağını tanımlar. Bir başarısızlık bağlamındaki herhangi bir başarısızlık tüm bağlamın başarısız olmasına neden olur.
Başarısızlık bağlamı, iç içe ifadelerin bir block ifadesindeki fonksiyon bağımsız değişkenleri veya ifadeler gibi başarısızlık ifadeleri olmasına izin verir.
Aşağıdaki liste Verse’teki tüm hata bağlamlarını içerir:
| |
| |
| |
| |
| |
|
spekülatif yürütme
Verse’te başarısızlık bağlamlarının faydalı bir yönü, eylemleri işlemeden deneyebileceğin anlamına gelen bir tür kurgusal yürütme şekli olmalarıdır. Bir ifade başarılı olduğunda ifadenin efektleri işlenir. Buna örnek olarak bir değişkenin değerinin değiştirilmesi gösterilebilir. Öte yandan ifade başarısız olursa ifadenin efektleri sanki ifade hiç gerçekleşmemiş gibi geri alınır.
Bu yöntemle, değişiklikleri biriktiren bir dizi eylem yürütebilirsin ancak bu eylemler hata bağlamının herhangi bir yerinde başarısız olursa geri alınacaktır.
Bunun işe yaraması için hata bağlamında çağrılan tüm fonksiyonlar transacts efekt belirleyicisine sahip olmak zorundadır.
Belirleyiciler
Verse’te belirleyiciler, semantik ile ilgili davranışı açıklar ve tanımlayıcılara ve belirli anahtar sözcüklere eklenebilir. Belirleyici sözdizimi, < ile > kullanarak anahtar sözcüğü bunların arasına koyar. Örneğin IsPuzzleSolved()<decides><transacts> : void.
Aşağıdaki bölümlerde Verse’teki tüm belirleyiciler ve bunları ne zaman kullanabileceğin açıklanıyor.
Efekt Belirleyicileri
Verse’te efektler bir fonksiyonun sergilemesine izin verilen davranış kategorilerini belirtir. Efekt belirleyicileri şunlara ekleyebilirsin:
Bir fonksiyon tanımındaki addan sonra gelen ():
name()<specifier> : type = codeblock.classanahtar sözcüğü:name := class<specifier>():.
Efekt belirleyiciler iki kategoriye ayrılır:
Özel: Bir fonksiyona veya
classanahtar sözcüğüne özel efekt belirleyicilerinden yalnızca birini ekleyebilirsin veya hiçbirini ekleyemezsin. Özel bir efekt belirleyicisi eklenmezse varsayılan efektno_rollbackşeklinde olur.Katkı: Bir fonksiyona veya
classanahtar sözcüğüne katkı efekti belirleyicilerinin tümünü veya bazılarını ekleyebilirsin ya da hiçbirini ekleyemezsin.
| Örnek | Etki |
|---|---|
no_rollback: Özel bir efekt belirtilmediğinde varsayılan efekttir. | |
Özel Efektler | |
transacts: Bu efekt, fonksiyon tarafından gerçekleştirilen herhangi bir eylemin geri alınabileceğini belirtir. transacts efekti, bir değiştirilebilir değişkenin ( | |
varies: Bu efekt, fonksiyona eklenen aynı girdinin her zaman aynı çıktıyı üretemeyebileceğini belirtir. | |
computes: Bu efekt, fonksiyonun yan efektlerinin olmamasını gerektirir ve her zaman tamamlanmayabilir. Aynı bağımsız değişkenlerle birlikte sağlandığında fonksiyonun aynı sonucu vermesine yönelik denetlenmemiş bir gereklilik vardır. native belirleyicisine sahip olmayan ve aksi durumda | |
converges: Bu efekt, ilgili fonksiyonun yürütülmesinden kaynaklanan bir yan efekt olmayacağını ve fonksiyonun kesin olarak tamamlanacağını (sonsuz kadar yinelenmemesini) garanti eder. Bu efekt yalnızca native belirleyicisine sahip fonksiyonlarda görünebilir ancak bunun gerçekleşmesi derleyici tarafından denetlenmez. Bu efektin gerçekleşmesi için varsayılan sınıf değerlerinin sağlanması için kullanılan kod veya global değişken değerleri gereklidir. | |
Katkı Efektleri | |
decides: Fonksiyonun başarısız olabileceğini ve bu fonksiyonu çağırmanın başarısız olabilir bir ifade olduğunu belirtir. | |
suspends: Fonksiyonun asenkron olduğunu belirtir. Fonksiyon gövdesi için bir asenk. bağlamı oluşturur. |
Tüm durumlarda belirli bir efekte sahip bir fonksiyonu çağırmak için çağıranın da o efekte sahip olması gerekir.
Erişim Belirleyicileri
Erişim belirleyiciler bir üye ile neyin nasıl etkileşimde bulunabileceğini tanımlar. Erişim belirleyiciler aşağıdakilere uygulanabilir:
Bir üye için tanımlayıcı:
name<specifier> : type = valueBir üye için
varanahtar sözcüğü:var<specifier> name : type = value
Sınıf Belirleyicileri
Sınıf belirleyiciler, sınıfların veya üyelerinin, bir sınıfın alt sınıfını oluşturup oluşturamayacağın gibi belirli özelliklerini tanımlar.
abstract: Bir sınıf veya sınıf metodunda abstract belirleyicisi olduğunda sınıfın örneğini oluşturamazsın. Soyut sınıflar, kısmi uygulamalı bir üst sınıf veya ortak bir arayüz olarak kullanılmaya yöneliktir. Bu anlayış, bir üst sınıfın örneklerine sahip olmanın mantıklı olmadığı ancak özellikleri ve davranışları benzer sınıflar arasında tekrar etmek istemediğin durumlar için faydalıdır. | |
concrete: Bir sınıfta concrete belirleyicisi olduğunda sınıfı boş bir arketiple oluşturmak mümkündür. Bunun sonucunda sınıfın her alanı varsayılan bir değere sahip olmak zorundadır. Bir somut sınıfın her alt sınıfı örtük olarak somuttur. Bir somut sınıfın bir soyut sınıftan doğrudan devralabilmesi için her iki sınıfın da aynı modülde tanımlanmış olması gerekir. | |
unique: unique belirleyicisi, bir sınıfı benzersiz yapmak için sınıfa uygulanabilir. Verse, benzersiz bir sınıfın bir örneğini oluşturmak için ortaya çıkan örneğe benzersiz bir kimlik ayırır. Bu işlem, benzersiz sınıf örneklerinin, kimlikleri karşılaştırılmak suretiyle eşitlik açısından karşılaştırılmasına imkan tanır. Benzersiz belirleyicisi olmayan sınıfların böyle bir kimliği yoktur, dolayısıyla bunlar eşitlik açısından yalnızca alanlarının değerlerine göre karşılaştırılabilir. Buna göre, benzersiz sınıflar = ve <> işleçleriyle karşılaştırılabilir, ayrıca karşılaştırılabilir türün alt türleridir. |
Uygulama Belirleyicileri
Kod yazarken uygulama belirleyicileri kullanmak mümkün değildir ancak UEFN API’lerine baktığında bunları göreceksin.
native_callable: Bir örnek metodunun hem yerel (C++ dilinde uygulanan) olduğunu hem de diğer C++ kodlarıyla çağrılabileceğini belirtir. Bu belirleyicinin bir örnek yönteminde kullanıldığını görebilirsin. Bu belirleyici alt sınıflara yayılmaz, dolayısıyla bu belirleyiciye sahip bir metodu geçersiz kılarken onu bir tanıma eklemen gerekmez. |
Yerelleştirme Belirleyicisi
Yeni bir mesaj tanımlarken localizes belirleyicisini kullanman gerekir. Bu özellikle, değişken message türüne sahip olduğunda ve değişkeni bir string değeri ile başlatacağın zaman gereklidir.
# The winning player's name:
PlayerName<localizes> : message = "Player One"# Build a message announcing the winner.
Announcement<localizes>(WinningPlayerName : string) : message = "...And the winner is: {WinningPlayerName}"
Billboard.SetText(Announcement("Player One"))Daha önce oluşturulmuş bir mesajla bir üye değeri başlatırken localizes belirleyicisini kullanman gerekmez çünkü localizes belirleyicisi yalnızca yeni mesajlar içindir.
PlayerOne<localizes> : message = "Player One"
# The winning player's name:
PlayerName : message = PlayerOneÖznitelikler
Verse’te öznitelikler, Verse dilinin dışında kullanılan davranışı açıklar (Verse semantiğini açıklayan belirleyicilerin aksine). Öznitelikler, kod satırında tanımların önüne eklenebilir.
Öznitelik sözdizimi, @ ve ardından anahtar sözcük kullanır.
denetim akışı
Denetim akışı bir bilgisayarın talimatları yürütme sırasıdır. Verse, programında bu akışı kontrol etmek için kullanabileceğin farklı ifadelere sahiptir.
Blok
Verse bir kod blokundan önce bir tanımlayıcı gerektirdiğinden block ifadeleri kod bloklarını nasıl iç içe yerleştirdiğini ifade eder. İç içe yerleştirilmiş kod bloğu, bir kod bloğuna benzer şekilde davranır. Kod bloklarında olduğu gibi blok ifadesi de yeni bir iç içe kapsam gövdesi sunar.
| blok |
|---|
Sonuç: |
Daha fazla bilgi için Blok kısmına bakabilirsin.
If
if ifadesiyle programın akışını değiştiren kararlar verebilirsin. Diğer programlama dillerinde olduğu gibi Verse’teki if ifadesi de koşullu yürütmeyi destekler ancak Verse’te koşullar kararı yönlendirmek için başarı ve başarısızlığı kullanır.
| If | if ... then |
|---|---|
Sonuç: | Sonuç: |
| if ... else | if ... else if ... else |
|---|
Aşağıdaki örnekte IsLightOn? başarılı olursa if ifadesi kod bloku false, IsLightOn? başarısız olursa true olur. Bundan sonra logic sonucu NewLightState içinde depolanır.
NewLightState :=
if (IsLightOn?):
Light.TurnOff()
false
else:
Light.TurnOn()
true
Verse’te if ifadesinin faydalarından biri, başarısız olabilir ifadeleri denemene olanak verilmesi ve başarısız olurlarsa eylemlerin hiç gerçekleşmemiş gibi geri alınabilmesidir. Bu özellik hakkında daha fazla bilgi için Kurgusal Yürütme kısmına bakabilirsin.
Daha fazla bilgi için If kısmına bakabilirsin.
Case
case ifadeleri ile bir programın akışını seçenek listesinden denetleyebilirsin. Verse’te case deyimi, bir değeri birden çok olası değere karşı test etmeye (= kullanıyormuşsun gibi) ve hangisinin eşleştiğine göre kod çalıştırmaya olanak tanır.
| kılıf |
|---|
Daha fazla bilgi için Case kısmına bakabilirsin.
Loop
loop ifadesiyle döngü blokundaki ifadeler, döngünün her yinelemesi için tekrar edilir.
| döngü |
|---|
Sonuç: Bir |
Aşağıdaki örnekte oyun devam ettikçe her ToggleDelay değeri kadar saniyede bir platform görünür ve kaybolur.
loop:
Sleep(ToggleDelay) # Sleep(ToggleDelay) waits for ToggleDelay seconds before proceeding to the next instruction.
Platform.Hide()
Sleep(ToggleDelay)
Platform.Show() # The loop restarts immediately, calling Sleep(ToggleDelay) again.
Daha fazla bilgi için Loop kısmına bakabilirsin.
Döngüleri Durdurma
Bir loop bloku sonsuza kadar devam eder. Döngüyü durdurmak için break ile veya fonksiyonun return ifadesi ile döngüden çıkış yapabilirsin.
| Döngü ve Kesme | loop ve return |
|---|---|
Sonuç: Bir | Sonuç: Bir |
| iç içe loop ve break |
|---|
Sonuç: Bir |
Daha fazla bilgi için Loop ve Break kısmına bakabilirsin.
For
Bazı durumlarda for döngüsü olarak adlandırılan for ifadesi bir loop ifadesiyle aynıdır ancak for ifadeleri her defasında bir değer olmak üzere bir değer sekansı üretmek için üreteç kullanır ve her değere bir ad verir.
Örneğin for(Value : 1..3) ifadesi 1, 2, 3 sıralamasını oluşturur ve sıralamadaki her bir sayıya her yineleme için Value adı verilir. Böylece for döngüsü üç kez çalışır.
for ifadesi iki kısımdan oluşur:
Yineleme belirtimi: Parantez içindeki ifadeler. Birinci ifade bir oluşturucu olmalıdır ancak diğer ifadeler bir sabit başlatma veya filtre olabilir.
Gövde: Kod blokundaki parantezden sonra gelen ifadeler.
| için | filtreli for |
|---|---|
Sonuç: | Sonuç: |
| birden fazla üreteçli for | iç içe for blokları |
|---|---|
Sonuç: | Sonuç: İç içe |
Daha fazla bilgi için For kısmına bakabilirsin.
ertelemek
defer ifadesi, return ifadesinde olduğu gibi herhangi bir sonuç ifadesi de dahil olmak üzere, program denetimini defer ifadesinin belirdiği kapsamın dışına aktarmadan hemen önce yürütülür. Program denetiminin nasıl aktarıldığı önemli değildir.
| ertelemek | çıkıştan önce defer |
|---|---|
Sonuç: | Sonuç: |
Defer ile karşılaşılmadan önce erken bir çıkış gerçekleşirse defer ifadesi yürütülmez.
| erken dönüş ile defer | iptal edilmiş bir eşzamanlı görev ile defer |
|---|---|
Sonuç: | Sonuç: |
Aynı kapsamda görünen birden fazla defer ifadesi birikir. İfadelerin yürütüldüğü sıra, karşılaşıldığı sıranın tersidir: ilk giren son çıkar (FILO) sırası. Belirli bir kapsamda karşılaşılan son defer ilk önce yürütülür, bu son karşılaşılan defer içindeki ifadeler daha önce karşılaşılan ve daha sonra yürütülen diğer defer ifadeleri tarafından temizlenecek bağlama başvurabilir.
| Bir kod blokunda birden fazla defer ifadesi. | Farklı kod bloklarında birden fazla defer ifadesi. |
|---|---|
Sonuç: | Sonuç: |
Zaman Akışı ve Eşzamanlılık
Zaman akışı kontrolü, Verse programlama dilinin ana unsurlarından biridir ve eşzamanlı ifadelerle gerçekleştirilir. Eşzamanlılık hakkında daha fazla bilgi almak için Eşzamanlılığa Genel Bakış kısmına bakabilirsin.
yapılandırılmış eşzamanlılık
Yapılandırılmış eşzamanlılık ifadeleri, asenkron zaman akışını belirtmek ve asenkron ifadelerin engelleyici niteliğini belirli bir asenkron bağlam kapsamına (bir asenkron fonksiyon gövdesi gibi) kısıtlı bir yaşam süresi ile değiştirmek için kullanılır.
Bu, ilişkili kapsamlarıyla kısıtlanan block, if, for ve loop gibi yapılandırılmış kontrol akışına benzer.
| senk | Dal |
|---|---|
Kod blokundaki tüm ifadeleri eşzamanlı olarak yürütür ve |
|
Sonuç: Bir | Sonuç: |
| race | rush |
|---|---|
|
|
Sonuç: Bir | Sonuç: Bir |
yapılandırılmamış eşzamanlılık
Yapılandırılmamış eşzamanlılık ifadeleri (sadece spawn bu türdendir), belirli bir asenk. bağlam kapsamıyla sınırlı olmayan ve yürütüldüğü kapsamın ötesine genişleme potansiyeli barındıran bir yaşam süresine sahiptir.
| Çıkar |
|---|
Bir |
Sonuç: |
Task
Görev (task), o sırada yürütülmekte olan asenk. bir fonksiyonun durumunu göstermek için kullanılan bir objedir. Görev objeleri, asenk. bir fonksiyonun nerede askıya alındığını ve söz konusu askıya alma noktasındaki yerel değişkenlerin değerlerini belirlemek için kullanılır.
# Get task to query / give commands to
# starts and continues independently
Task2 := spawn{Player.MoveTo(Target1)}
Task2.Await() # wait until MoveTo() completed
Modüller ve Yollar
Verse modülü, yeniden dağıtılabilen ve bağımlı olunabilen atomik bir kod birimidir ve bağımlılıkları bozmadan zaman içinde gelişebilir. Diğer Verse dosyalarındaki kod tanımlarını kullanmak için Verse dosyan içine bir modül aktarabilirsin.
using: Bir Verse modülünün içeriğini kullanabilmek için modülü yoluna göre belirtmen gerekir. | |
module: Bir projedeki klasörlere göre sunulan modülün dışında, modüller .verse dosyası içinde |
Daha fazla bilgi için Modüller ve Yollar kısmına bakabilirsin.