Generyczne tablice w Ruście
Postanowiłem ostatnio w ramach ćwiczenia "przetłumaczyć" symulator czarnej dziury na Rusta. Na początek zdecydowałem się stworzyć bibliotekę obsługującą geometrię różniczkową (rachunek tensorowy, metrykę itp.). Natknąłem się przy tym dość szybko na pewien problem.
Rust i tablice
Tensory są obiektami mającymi pewną ustaloną liczbę współrzędnych, zależną od wymiaru przestrzeni, na której funkcjonują. Np. w przestrzeni n-wymiarowej wektory mają współrzędnych, tensory rzędu 2 (np. metryka) mają ich itp. Do reprezentacji takich obiektów idealne są tablice.
Rust radzi sobie z tablicami bez problemu. N-elementową tablicę z elementami typu T zapisuje się w Ruście jako [T; N]
. I wszystko byłoby fajnie, gdyby nie drobny szczegół - chciałbym, żeby mój kod był niezależny od wymiaru przestrzeni.
Problem
Rust posiada możliwość tworzenia tzw. typów generycznych. Są to typy danych, w których możemy określić, jakiego typu mają być ich wewnętrzne szczegóły. Np., moglibyśmy łatwo stworzyć generyczny wektor 3-wymiarowy:
1 2 3 |
struct Vector3<T> { coords: [T; 3] } |
Co jednak, gdybyśmy chcieli stworzyć wektor n-wymiarowy?
1 2 3 |
struct Vector<T,N> { coords: [T; N] // nie zadziała } |
Nic z tego. Nie ma w Ruście sposobu na wyrażenie tego, żeby parametrem typu była długość tablicy.
Sprawa wydawała się beznadziejna, ale przypadkiem natknąłem się na kod, który zasugerował, że rozwiązanie może istnieć.
(więcej…)