TypeScript'te lambda dönüş türlerinin imzası
Aşağıdaki TypeScript'te her iki fonksiyon da aynı, sadece demoTwo'da dönüş türünü açıkça belirtmeye çalışıyorum. Dönüş türü, kendisi bir fonksiyon alan bir fonksiyondur. Sorum şu: Hiç kullanılmayacak olmasına rağmen neden whyThis ile temsil edilen parametre adını vermek zorundayım? O pozisyonda bir şey olmadan kod derlenmeyecektir.
function demoOne() {
return function(input: () => string) : void {
var result = input();
console.log("Foo:",result);
}
}
function demoTwo(): (whyThis:() => string) => void {
return function(input: () => string) : void {
var result = input();
console.log("Bar:",result);
}
}
var sampleInput = () => "wibble";
demoOne()(sampleInput);
demoTwo()(sampleInput);
Net olmak gerekirse, burada sorduğum şeyin Scala'daki eşdeğer kodu şudur:
object Program {
def demoTwo(): (() => String) => Unit = {
def tmp(input: () => String): Unit = {
val result = input()
println("Bar: " + result)
}
return tmp
}
def main(args: Array[String]): Unit = {
val sampleInput = () => "wibble"
demoTwo()(sampleInput)
}
}
Eğer demoTwo deklarasyonlarını yan yana koyarsak şuna sahip oluruz:
function demoTwo(): (whyThis:() => string) => void { //TS
def demoTwo(): (() => String) => Unit = { //Scala
Tek büyük fark, TS'nin whyThis konumunda bir şey gerektirmesi ve Scala'nın gerektirmemesi. Bunun nedeni ne olmalı?
Cevap #1
Bence karışıklık, imzaların tanımlanma biçiminden kaynaklanıyor. Aşağıdaki 3 imzaya dikkat edin
(number) => Void
(x : number) => Void
(_ : number) => Void
Son ikisi, number türünde bir argüman alan boş (void) fonksiyonların imzalarıdır. Ancak birincisi, adı number olan Any türünde bir argüman alan bir fonksiyondur. Yani dil, bir türden önce bir isim gerektirir ve eğer tür atlanırsa, Any türü varsayılır.
Yani,
(() => string) => void
Geçerli değil çünkü '() => string' geçerli bir isim değil ve derleyici bunu böyle analiz etmeye çalışırken kafası karışıyor.
En kısa form ''_ : type'' kullanmak olacaktır.
Ama isimlerin çıkarılıp yalnızca türün kullanılması ya da ismin isteğe bağlı olması daha güzel olurdu diye katılıyorum. Neden böyle bir tasarım kararı verdiklerinden emin değilim, belki mevcut JavaScript ok fonksiyonlarıyla (tür olmadan) karışıklığı önlemek içindir.
Cevap #2
TypeScript'teki tüm fonksiyon parametrelerinin bir isme sahip olması gerekir, onları kullanıp kullanmamayıza bakılmaksızın. Eklediğiniz şey çağrı imzasıdır, çalışma zamanında kullanılmayan ancak kod yazarken size yardımcı olacak bir şeydir.
Her iki örnek için de oluşturulan JavaScript dosyasına bakarsanız, ikisi de tamamen aynı kodu üretecektir:
function demoOne() {
return function (input) {
var result = input();
console.log("Foo:", result);
};
}
function demoTwo() {
return function (input) {
var result = input();
console.log("Bar:", result);
};
}
DÜZENLEME: Yani parametrenin çalışma zamanında hiç kullanılmadığı konusunda doğrusunuz, ancak bu parametreler derleme zamanında (editörünüze bağlı olarak) görünebilir. Bir çağrı imzası eklemezseniz, editör çalışma zamanı parametrelerinden bir imza çıkarır ve bunu derleme zamanında gösterir.
Çağrı imzanızı, kodunuzun nasıl kullanıldığını ve parametrelerin neyi temsil ettiğini diğer insanlara iletmenin bir yolu olarak düşünebilirsiniz; kodunuzu kullanacak kişiler için çok anlaşılır olacak şekilde yazılmıştır.
İşte Visual Studio, fonksiyonlarınızın üzerinde fare ile durduğunuzda gösterdiği şey; bu kod tanımları, bu fonksiyonları çağırırken VSCode ve diğer editörlerde de görünür:
Demo bir:
Demo iki:

