March 29, 2022

Merhaba,

Sonunda, Ali hocanın kitabı sayesinde, return belirteçi ile birlikte inout'u tam manasıyla öğrendim diyebilirim. Öyle ki şablon parametresi kullandığınızda ona bile ihtiyaç yokmuş. Dersin konusu şurada:

http://ddili.org/ders/d/islev_parametreleri.html#ix_islev_parametreleri.inout,%20parametre

Bu özelliğe de alıştığımız "return" Türkçe anlamı gibi bakmamak gerekiyor; yani giriş/çıkış değil. Çünkü zaten ref belirteçi bu görevi yerine getiriyor ama inout belirteçi, dönen değerin const mu, immutable mı yoksa başka bir özellikte mi olduğunu taşıyabiliyor. Bu güzel özelliği denemek için kitaptaki örneği biraz geliştirdim:

//sliceOff Function:
auto kenardanDilimle(R)(R[] d, size_t u = 0)/*
                (inout(R[]) d, size_t u = 0)//*/
{
  if(u == 0) return d[];

  return d.length > u << 1 ? d[u .. $ - u] : [];
}

import std.stdio;

void main() {
  //immutable
  double[][] veri = [ [ 3, 4 ],
       [ 0, 1, 2, 3, 4, 5, 6 ],
       [ 1, 2, 3, 4, 5 ],
       [ 2, 3, 4, 5],
       [ 3, 4, 5],
       []
  ];

  veri[1].kenardanDilimle(1)[] /= 5;
  veri[1].writeln;
}/* ÇIKTISI:
[0, 0.2, 0.4, 0.6, 0.8, 1, 6]
*/

Tabi gizlediğim satırları (örn. immutable satırını) açarsanız dilimlenen elemanların değerlerini değiştirdiğim için hata verecektir. Zaten hata vermesi bile çalıştığını gösteriyor ya. Neyse örnek biraz ağır gelebilir. Dilim içermeyen aşağıdaki şu örnek daha iyi:

import std.stdio;

auto katla(inout(uint) n) {/*
auto katla(uint n) {//*/
	return n << 1; // sola kaydırarak ikiye katlar
}
void main() {
	const uint yıl = 2022;
	typeid(yıl.katla).writeln(", ", yıl.katla);
	
	auto böl = yıl.katla;
	   //böl /= 2;                          // DERLAMA HATASI: çünkü
	assert(is(typeof(böl) == typeof(yıl))); // her ikiside const'dur
	böl.writeln;
}/* ÇIKTISI:
const(uint), 4044
4044
*/

Girişte bahsettiğim return ref belirteçi hakkındaki tartışma şurada:
https://forum.dlang.org/thread/hffznlsdlrlofogidjzx@forum.dlang.org

Başarılar...