Funkcja zwracająca różne typy danych

Funkcja zwracająca różne typy danych
D1
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 8 lat
  • Postów:165
0

Chciałbym aby Funkcja zwracała mi różne dane w zależności od przekazanych parametrów. Jeśli wartość paramtru1 będzie 'A' to funkcja ma zwrócić Stringa, jeśli wartość parametru1 będzie 'C' to funckaj zwraca datę itd.
Jest to możliwe do wykonania?

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Tuchów
  • Postów:12167
0

Jest możliwe - użyj typu Variant; Tyle że możliwości nie są ograniczone i lepiej by było gdybyś wyjaśnił przeznaczenie takiej funkcji.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 1x, ostatnio: flowCRANE
D1
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 8 lat
  • Postów:165
0

To raczej nie sprawdzi się u mnie, chyba że coś źle zrozumiałem.

Ja mam zmienne już określone i niejestem w stanie ich zmienić bo bym musiał przebudować cały kod. Chciałem stworzyć uniwersalną funkcję, która by przypisywała wartość w zależności od parametrów. Wszystkie wartości początkowo widnieją jako stringi w tablicy. Po podaniu w parametrze funkcji słowa kluczowego np. "data" wartość funkcji od razu stawałaby się datą, gdy słowo kluczowe będzie "nazwisko" to wtedy wynikiem jest string, a gdy np. słowo kluczowe to "numer" wtedy wynikiem funkcji jest integer.

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Tuchów
  • Postów:12167
2

Chciałem stworzyć uniwersalną funkcję, która by przypisywała wartość w zależności od parametrów.

No dobrze, ale jaki typ miałaby zwracać ta funkcja, żeby mogła zwracać dowolne dane? Jedyne co mi do głowy przychodzi to goły Pointer, jednak kod musiałbyś przerobić;

Po podaniu w parametrze funkcji słowa kluczowego np. "data" wartość funkcji od razu stawałaby się datą, gdy słowo kluczowe będzie "nazwisko" to wtedy wynikiem jest string, a gdy np. słowo kluczowe to "numer" wtedy wynikiem funkcji jest integer.

Taki efekt możesz uzyskać za pomocą przeładowywania:

Kopiuj
uses
  SysUtils;

  function Convert(const AValue: String): TDateTime; { overload; }
  begin
    Result := StrToDate(AValue);
  end;

  function Convert(const AValue: String): String; { overload; }
  begin
    Result := AValue;
  end;

  function Convert(const AValue: String): Integer; { overload; }
  begin
    Result := StrToInt(AValue);
  end;

W Lazarusie nie trzeba zakańczać deklaracji tych funkcji słówkiem overload (dlatego są zaremowane);
I teraz możesz używać teoretycznie jednej funkcji, która zwracać będzie dane różnego typu; Ograniczenie jest takie, że typy danych muszą się w każdej z nich różnić - albo typy parametrów, albo typ zwracany; Dzięki temu możliwe będą poniższe wywołania:

Kopiuj
var
  dtValue:  TDateTime;
  strValue: String;
  intValue: Integer;
begin
  dtValue  := Convert('01:03:56');
  strValue := Convert('foo bald');
  intValue := Convert('12345678');

Możesz też ustalić ten sam typ zwracany (np. String), ale różne typy argumentów.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 8x, ostatnio: flowCRANE
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
2

@dani17: kombinujesz cholernie pod górę.
Jeśli potrzebujesz, aby wywołanie getCostam('a') zwracało integer, a getCostam('b') - ciąg znaków, utwórz odrębne metody getCostamA() oraz getCostamB() - to jedyna słuszna oraz poprawna metoda.


edytowany 3x, ostatnio: Patryk27
flowCRANE
Patrz wyżej ;)
Patryk27
A czy ja mówię, że nie można inaczej? Można - tyle że #refaktoryzowałbym ;-)
D1
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 8 lat
  • Postów:165
0
Patryk27 napisał(a):

@dani17: kombinujesz cholernie pod górę.
Jeśli potrzebujesz, aby wywołanie getCostam('a') zwracało integer, a getCostam('b') - ciąg znaków, utwórz odrębne metody getCostamA() oraz getCostamB() - to jedyna słuszna oraz poprawna metoda.

no dobrze, ale to musiałbym takich metod stworzyć kilkadziesiąt. mam 20 róznych słów kluczowych, które mają zwracać String, 20 zwracających integer i kilka zwracających datę. dlatego chciałbym to stworzyć w jednej funkcji i najlepiej napisać if (argument = 'slowo') or (argument = 'inne slowo') then result: string else result: inetger;

to nie jest poprawny zapis, wiem, ale chcę w ten sposób pokazać co chciałbym osiągnąć.

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
2

no dobrze, ale to musiałbym takich metod stworzyć kilkadziesiąt.
No to stwórz ich kilkadziesiąt - przecież już dawno temu miałbyś je napisane (zakładając nawet, że nie masz automatycznego generatora getterów/setterów w środowisku) :P

Naprawdę nie ma co robić sobie drogi na skróty - w programowaniu liczy się dokładność. Robiąc coś na odczep zachowujesz sobie jedynie pięć minut dzisiaj, tracąc pięć godzin w przyszłości na szukaniu błędu.


flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Tuchów
  • Postów:12167
1
dani17 napisał(a)

dlatego chciałbym to stworzyć w jednej funkcji i najlepiej napisać if (argument = 'slowo') or (argument = 'inne slowo') then result: string else result: inetger;

Nie możesz napisać jednej funkcji, która może zwracać trzy różne typy danych - albo String, albo TDate, albo Integer; Musisz określić konkretny typ danych zwracanych przez funkcję; Możesz skorzystać z typu Variant, aby móc zwracać dane różnych typów, jednak musiałbyś zmienić również typy danych w programie; W ogóle to nie ma się nad czym zastanawiać;

no dobrze, ale to musiałbym takich metod stworzyć kilkadziesiąt. mam 20 róznych słów kluczowych, które mają zwracać String, 20 zwracających integer i kilka zwracających datę.

Skoro jest ich tyle to napisz sobie trzy przeładowane (dla każdego typu jedna).


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
woolfik
  • Rejestracja:ponad 17 lat
  • Ostatnio:około 8 godzin
  • Postów:1595
0
dani17 napisał(a):

no dobrze, ale to musiałbym takich metod stworzyć kilkadziesiąt. mam 20 róznych słów kluczowych, które mają zwracać String, 20 zwracających integer i kilka zwracających datę. dlatego chciałbym to stworzyć w jednej funkcji i najlepiej napisać if (argument = 'slowo') or (argument = 'inne slowo') then result: string else result: inetger;

to nie jest poprawny zapis, wiem, ale chcę w ten sposób pokazać co chciałbym osiągnąć.

Nie wiem jak w lazarusie ale w delphi da się to zrobić używając generyków i żeby przyspieszyć TDictionary.

Kopiuj
TVirtualFileClass = class
    public
        class function GetResult: Variant virtual; abstract;
    end;

TFileTypeClass = class of TVirtualFileClass;

TFileTypeClassA = class(TVirtualFileClass )
    public
        class function GetResult: Variant; override;
    end;

TFileTypeClassB = class(TVirtualFileClass )
    public
        class function GetResult: Variant; override;
    end;

Każda klasa będzie miała swoją funkcję GetResult i wywołanie będziesz miał tylko:

Kopiuj
RegistrationClass(const aClassType: TFileTypeClass);

wewnątrz możesz sobie to dodawać do swojego dicta lub klasy dziedziczącej z dicta np tak:

Kopiuj
type 
TKBFilesType = class(TDictionary<string, TFileTypeClass>)

to oczywiście tylko przykładowe definicje ale ja mam tak zrobione np wczytywanie plików operuję na jednym typie czyli

Kopiuj
 TNazwaKlasy = class of TNazwaKlasyVirtualnej

i reszta dzieje się w definicjach poszczególnych klas. Nie ma dzięki temu w kodzie warunków: if ExtractFileExtention(pFilneName) = 'txt' then ... else if ...

Kopiuj
D1
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 8 lat
  • Postów:165
0
Patryk27 napisał(a):

no dobrze, ale to musiałbym takich metod stworzyć kilkadziesiąt.
No to stwórz ich kilkadziesiąt - przecież już dawno temu miałbyś je napisane (zakładając nawet, że nie masz automatycznego generatora getterów/setterów w środowisku) :P

Naprawdę nie ma co robić sobie drogi na skróty - w programowaniu liczy się dokładność. Robiąc coś na odczep zachowujesz sobie jedynie pięć minut dzisiaj, tracąc pięć godzin w przyszłości na szukaniu błędu.

Tak też zrobię, w końcu wywołanie takiej funkcji będzie niemal identyczne jak to czego chciałem. Jedynie zamiast wpisywać słowo kluczowe jako parametr to będzie się ono znajdowało w nazwie funkcji.

Ale teraz mam inne pytanie. Jeżeli mam zmienną Imie: String; to czy da się zrobić aby jakaś inna zmienna przyjęła jako wartość nazwę innej zmiennej? I tak samo w drugą stronę, w sumie bardziej mi na tym zależy. Mam Tablica: Array of String = ('Imie', 'Nazwisko', 'Miasto'); i czy teraz da się zrobić coś takiego:

Kopiuj
for I := 0 to Length(Tablica) - 1 do
  Zmienna{Tablica[I]} := Get{Tablica[I]}
 

Oczywiście mam zadeklarowane zmienne które nazywają się tak jak wartości tablicy. Czy jednak nie da się tego przyśpieszyć i trzeba robić tak:

Kopiuj
for I := 0 to Length(Tablica) - 1 do
  begin
    if Tablica[I] = 'Imie' then
      Imie := GetImie;
    if Tablica[I] = 'Nazwisko' then
      Nazwisko := GetNazwisko;
    if Tablica[I] = 'Miasto' then
      Miasto := GetMiasto;
  end;
 
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Znowu próbujesz sobie torować drogę na skróty :P

Teoretycznie mógłbyś spróbować utworzyć sobie klasę zawierającą metody GetImie(), GetNazwisko() oraz GetMiasto() (przy okazji: nie wykorzystuj polskiego nazewnictwa w kodzie, nigdy) oraz pobawić się z RTTI, natomiast to by było czysto dla zabawy i bardzo nie chciałbym spotkać czegoś takiego w normalnym, produkcyjnym kodzie.


Zobacz pozostałe 5 komentarzy
Patryk27
Sugerujesz, że powinniśmy pozwalać młodym kierowcom wymuszać pierwszeństwo na skrzyżowaniach bo oni się jeszcze uczą? Albo pozwalać młodym dzieciom kraść? Podobnie tu - od początku należy wpajać dobre nawyki.
LukeJL
Jeśli to się dzieje na udawanych skrzyżowaniach na placu manewrowym, to niech sobie wymuszają.
LukeJL
Ktoś może sobie dla siebie pisać nawet po chińsku, ale każdy kod wypuszczany do innych ludzi (niezależnie czy w pracy, na zlecenie czy open source) powinien być po angielsku, wiadomo.
LukeJL
od początku należy wpajać dobre nawyki. -- zgadzam się. Z pisaniem po polsku "bo tylko ja będę korzystał" jest taki problem, że nigdy tego nie wiesz do końca. jeśli ktoś pisze po polsku to zamyka się na możliwość zadania pytania na StackOverflow nawet, bo nikt nie zrozumie jego kodu i nikt nie będzie mógł mu pomóc. Więc jest to bardzo krótkowzroczne i warto jak najszybciej przejść na angielski, nawet jak się stosuje tę karygodną praktykę pisania po polsku.
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Tuchów
  • Postów:12167
0

W dalszym ciągu wygląda to na kosmiczne kombinacje; Przy czym zamiast podawać nazwy zmiennych (i trzymać te nazwy w tablicy), możesz skorzystać z typu wyliczeniowego i rozróżnienie wartości zrobić czytelnie w instrukcji wyboru:

Kopiuj
type
  TFieldKind = (fkName, fkSurname, fkCity);

function Foo(AFieldKind: TFieldKind): String;
begin
  case AFieldKind of
    fkName:    Result := GetName();
    fkSurname: Result := GetSurname();
    fkCity:    Result := GetCity();
  end;
end;

I wywołania:

Kopiuj
Name    := Foo(fkName);
Surname := Foo(fkSurname);
City    := Foo(fkCity);

Ale takie cuś raczej nie ma sensu - wygodniej będzie zrobić sobie więcej funkcji, nazwać je sensownie i używać; Przy czym jeśli funkcje mają elementy wspólne to można je pogrupować.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 3x, ostatnio: flowCRANE
D1
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 8 lat
  • Postów:165
0
Patryk27 napisał(a):

Znowu próbujesz sobie torować drogę na skróty :P

Teoretycznie mógłbyś spróbować utworzyć sobie klasę zawierającą metody GetImie(), GetNazwisko() oraz GetMiasto() (przy okazji: nie wykorzystuj polskiego nazewnictwa w kodzie, nigdy) oraz pobawić się z RTTI, natomiast to by było czysto dla zabawy i bardzo nie chciałbym spotkać czegoś takiego w normalnym, produkcyjnym kodzie.

Nie, nie. Ja mam to i tak napisane inaczej. Tylko byłem ciekawy czy coś takiego może istnieje. Bo jakby była jakaś funkcja która by to umożliwiła to kod byłby na pewno bardziej przejrzysty w tym konkretnym miejscu.

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Wcale nie byłby bardziej przejrzysty, tylko zaciemniony niejasną zależnością :P


0

a czy do takiego zadania nie byla by najlepsza fabryka po prostu ?

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

@Wybitny Młot: pokaż jak wykorzystujesz wzorzec fabryki w tym kontekście, to przecież nawet nie jest podobna sytuacja - rzuciłeś jakieś mądre słówko i pomyślałeś "o, rozwiązanie" :P


edytowany 1x, ostatnio: Patryk27
0

ehmmm oczysicei ze mozna wzorzec fabryki wykrozystac ... fabryka zwraca poporstu obiekt reagujac na dane slowa np. "string" , "date" , "int".

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
2

Pokaż, jak zastosowałbyś wzorzec fabryki do stworzenia getterów, bo tego jeszcze świat programistyczny nie widział, a przecież o gettery się rozchodzi.


edytowany 2x, ostatnio: Patryk27
flowCRANE
Obstawiam, że to trolling - ale z popkornem poczekajmy jeszcze;
0

A wiec wybacz nie przeczytalem dokladnie zadania , odpowiedzi do usuniecia :P Myslalem ze chodzi o obiekt ktory zwraca rozne typy danych do ktorych pozniej mozna przypisac jakies dane adekwatnie do rodzaju typu obiektu.

KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:około 8 godzin
  • Postów:2964
0

Chciałbym aby Funkcja zwracała mi różne dane w zależności od przekazanych parametrów. Jeśli wartość paramtru1 będzie 'A' to funkcja ma zwrócić Stringa, jeśli wartość parametru1 będzie 'C' to funckaj zwraca datę itd.
Jest to możliwe do wykonania?

W popularnych językach takich jak Java, C++, C#, Delphi nie jest możliwe zakodowanie czegoś takiego w systemie typów.
Jeżeli typ ma zależeć od wartości (a nie od typu wartości), to potrzebujesz języka, który potrafi tzw. "dependent types".
Takie języki to m.in. Agda, Coq, Idris i parę innych mniej znanych. Do pewnego stopnia da się zasymulować typy zależne w językach takich jak Haskell, Scala, Dotty.

https://en.wikipedia.org/wiki/Dependent_type

edytowany 1x, ostatnio: Krolik
WL
  • Rejestracja:około 21 lat
  • Ostatnio:około 2 miesiące
  • Postów:1082
0
Patryk27 napisał(a):

no dobrze, ale to musiałbym takich metod stworzyć kilkadziesiąt.
No to stwórz ich kilkadziesiąt - przecież już dawno temu miałbyś je napisane (zakładając nawet, że nie masz automatycznego generatora getterów/setterów w środowisku) :P

Naprawdę nie ma co robić sobie drogi na skróty - w programowaniu liczy się dokładność. Robiąc coś na odczep zachowujesz sobie jedynie pięć minut dzisiaj, tracąc pięć godzin w przyszłości na szukaniu błędu.

Zgoda. Tylko taka rada to jest właśnie na odczep się. Nie ma nic "fajniejszego" w programowaniu, jak robienie tego samego na kilkadziesiąt różnych sposobów. To był sarkazm, oczywiście...

Pytanie jest o FPC, a ja sie na tym nie znam, zatem...
Ale FPC ma coś takiego jak TValue? Albo - poprawnie obsługuje typy generyczne?

Tak czy siak; ja mam np. coś takiego:

Kopiuj
function AsBusinessObject<T : TBaseBusinessObjectQuery>: T;

A używa się tego tak:

Kopiuj
AsBusinessObject<TboPpTask>.Duration := 3.5;
AsBusinessObject<TboPpTextTask>.Duration := 'trzy i pół godziny';

Tak, mógłbym napisać kilkaset funkcji - ale ja jestem na to za leniwy.

WL
  • Rejestracja:około 21 lat
  • Ostatnio:około 2 miesiące
  • Postów:1082
0
Patryk27 napisał(a):

Znowu próbujesz sobie torować drogę na skróty :P

Teoretycznie mógłbyś spróbować utworzyć sobie klasę zawierającą metody GetImie(), GetNazwisko() oraz GetMiasto() (przy okazji: nie wykorzystuj polskiego nazewnictwa w kodzie, nigdy) oraz pobawić się z RTTI, natomiast to by było czysto dla zabawy i bardzo nie chciałbym spotkać czegoś takiego w normalnym, produkcyjnym kodzie.

Zatem nigdy przenigdy nie używaj LiveBindings w Delphi.
Trzymaj się z dala od wszelkiej maści ORMów i nomen-omen doskonałego Spring4Delphi lub DSharp.

Dlaczego? Bo tam bardzo intensywnie używa się RTTI, ale dla Ciebie to zabawa, a nie kod produkcyjny.
Jasne, można i tak. Ale można inaczej, lepiej, prościej i szybciej - a przy tym bardziej ogólnie.

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0
wloochacz napisał(a)

Bo tam bardzo intensywnie używa się RTTI, ale dla Ciebie to zabawa, a nie kod produkcyjny.
Jestem ciekaw, w którym to momencie powiedziałem, jakoby jakiekolwiek używanie RTTI było zabawą :-P

Napisałem, że w tym konkretnym przypadku, na moje oko, byłoby to zaciemnianiem kodu - co innego, gdy wykorzystuje się odrębny framework.


WL
  • Rejestracja:około 21 lat
  • Ostatnio:około 2 miesiące
  • Postów:1082
0
Patryk27 napisał(a):
wloochacz napisał(a)

Bo tam bardzo intensywnie używa się RTTI, ale dla Ciebie to zabawa, a nie kod produkcyjny.
Jestem ciekaw, w którym to momencie powiedziałem, jakoby jakiekolwiek używanie RTTI było zabawą :-P

W tym miejscu:
[...] oraz pobawić się z RTTI, natomiast to by było czysto dla zabawy i bardzo nie chciałbym spotkać czegoś takiego w normalnym, produkcyjnym kodzie.

Napisałem, że w tym konkretnym przypadku, na moje oko, byłoby to zaciemnianiem kodu - co innego, gdy wykorzystuje się odrębny framework.

Nie napisałeś tego - teraz to dopisałeś.
Poza tym, przecież framework to też kod.
A na moje oko, to pisanie n funkcji do tego samego, to jest zaciemnianie kodu.
Tego właśnie OP chciał uniknąć, a Ty radzisz mu coś takiego...

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0
wloochacz napisał(a)

W tym miejscu:
Tak, odnosząc się do tego konkretnego przypadku, a nie wszystkich możliwych sytuacji :-P

A na moje oko, to pisanie n funkcji do tego samego, to jest zaciemnianie kodu.
Podam może zatem przykład takiego genialnego rozwiązania (pozwoliwszy sobie odnieść się do innego języka): PHP, sklep Magento 1.

W PHP można utworzyć w klasach magiczne metody m.in. __get oraz __set, które umożliwiają odnoszenie się do klasowych pól bez ich formalnej deklaracji/definicji (te metody służą za akcesory, przyjmując jako parametr nazwę pola, do którego programista w kodzie próbuje się odnieść).

W konsekwencji spora liczba metod tak naprawdę pojawia się w kodzie z tyłka, niemożliwe staje się ich sensowne debugowanie czy skakanie po kodzie, nie mówiąc o braku podpowiadania składni przez IDE, na czym przy początku mojej pracy nieraz się przejechałem (bo przecież IDE nie podpowie literówki w getBaseSubtotalWitDiscount, skoro potencjalnie każda nazwa jest poprawna, w zależności od wnętrza metody __get).

O refaktoryzacji takiej metody również można pomarzyć.

Gdyby do każdego pola istniały odrębne akcesory, to faktycznie - codebase powiększyłby się o dodatkowe dziesiątki kilobajtów, natomiast stwarzujmy prawdę:

  1. Każde sensowne IDE i tak automatycznie potrafi paroma kliknięciami wygenerować oraz zaktualizować potrzebne metody.
  2. Czytelność kodu oraz możliwość jego statycznej analizy (głównie dla analizy typów) wzrosłaby ogromnie.
    Podałbym jakiś adekwatny przykład dla Delphi, lecz dawno temu przestałem już pisać w Pascalu i nic konkretnego nie przychodzi mi na myśl.

edytowany 2x, ostatnio: Patryk27
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)