Od czego zależy, czy w danym języku dozwala się robić unqualified import czy też żąda się zawsze pisania namespace?

0

Uwaga uwaga poniżej największa zbrodnia programisty C++ wystrzegać się jej zawsze

using namespace std;

Czy ja jestem osamotniony w tym, że uważam, że pisanie wszędzie co chwila std:: tylko zaciemnia kod, zaśmieca go i w ogóle jest zbędne?

Ale jednak przyjęło się, że using namespace cokolwiek dopuszczalne jest tylko i wyłącznie w ciele funkcji; na górze pliku jest niedopuszczalne.

Mam pytanie, może głupie, ale naprawdę nie wiem. Jak mamy taki C# na przykład, to czy dozwala się napisać na górze pliku:

using System.Collections.Generic;

I potem pisać już sobie tylko List zamiast obowiązkowo wszędzie System.Collections.Generic.List? Czy też może unqualified wildcard import jest zabroniony także w C#?

To samo pytanie dotyczy także rozmaitych Pythonów, Jav, i innych.

W skrócie: Czy ten zakaz jest charakterystyczny dla C++ czy dla języków programowania w ogóle?

0

W Javie masz zwykle pojedynczy import:
import java.util.ArrayList;
Wildcardy widuje się znacznie rzadziej:
import java.util.*;

0
Wibowit napisał(a):

W Javie masz zwykle pojedynczy import:
import java.util.ArrayList;
Wildcardy widuje się znacznie rzadziej:
import java.util.*;

Aha. Czy zatem w C++ dopuszczalne jest:

    #include <iostream>
    #include <vector>
    using std::vector;
    using std::cout;
    using std::endl;
     
    int main() {
    	vector<int> v{1,2, 3, 4};
    	for(auto i : v) cout << i  << endl;
    	return 0;
    }

Czy też jest to zabronione?

WYDAJE MI SIĘ, że też jest zabronione; mamy więc różnicę między C++ a Javą. Skąd się ona wzięła, jeśli rzeczywiście jest?

0

Język niczego nie narzuca. Dogadaj się z kumplami z pracy w jakim stylu chcecie pisać. Natomiast jeśli wszyscy w C++ dziwnie piszą to zmień język :)

0

Rzekomo w C++ ma to głębokie uzasadnienie.

  1. W pliku nagłówkowym jakiekolwiek using cośtam na górze przenosi się dla wszystkich plików importujących ten nagłówek;

  2. using namespace cośtam nawet w pliku implementacyjnym to proszenie się o kłopoty, bo jeśli jakaś moja funkcja / klasa ma tę samą nazwę co biblioteczna, to bez dokładnego zorientowania się, co eksportuje biblioteka i ogarniania reguł overloadingu mogę nawet nie orientować się, co jest wołane i że nie to, co bym chciał, by było wołane; co gorsza: nawet jak raz napiszę program i jest poprawny, potem aktualizuję bibliotekę która dodaje nowe funkcje to na nowej bibliotece może mi już przestać działać z tego powodu;

  3. Jeszcze jakies inne jeszcze bardziej techniczne uzasadnienia, których już nie pamiętam.

0

Jeśli using namespace std; importuje także metody to jest to zupełnie co innego niż zwykły import z Javy. Żeby zaimportować metody w Javie trzeba zrobić coś takiego: import static org.apache.commons.io.IOUtils.*;
Jest to jeszcze rzadsze niż importowanie klas hurtem: import jakaś.paczka.*;

  1. W pliku nagłówkowym jakiekolwiek using cośtam na górze przenosi się dla wszystkich plików importujących ten nagłówek;

Noo, brzmi jak proszenie się o problemy, więc tutaj bym się zgodził, że takie importowanie nie powinno mieć miejsca.

  1. using namespace cośtam nawet w pliku implementacyjnym to proszenie się o kłopoty, bo jeśli jakaś moja funkcja / klasa ma tę samą nazwę co biblioteczna, to bez dokładnego zorientowania się, co eksportuje biblioteka i ogarniania reguł overloadingu mogę nawet nie orientować się, co jest wołane i że nie to, co bym chciał, by było wołane; co gorsza: nawet jak raz napiszę program i jest poprawny, potem aktualizuję bibliotekę która dodaje nowe funkcje to na nowej bibliotece może mi już przestać działać z tego powodu;

Jak często zdarzają się takie problemy? Może trzeba niewiele zmian w stylu pisania kodu, by takich problemów uniknąć?

Problemy powinny generalnie zostać wychwycone przez testy.

Czy ja jestem osamotniony w tym, że uważam, że pisanie wszędzie co chwila std:: tylko zaciemnia kod, zaśmieca go i w ogóle jest zbędne?

Są tacy co dodają namiętnie zbędne this. przed wywołaniami metod i jeszcze twierdzą, że to zwiększa czytelność kodu.

1

W c# tylko takie podejścia widziałem

using System.Collections.Generic;

namespace something
{
	public class someclass
	{
	
	}
}
namespace something
{
	using System.Collections.Generic;
	
	public class someclass
	{
	
	}
}

A gdy występuje konflikt to się precyzuje.

0

Zdefiniuj: metody.

Przecież C++ wspiera funkcje nie będące metodami:

#include <iostream>

int jestem_sobie_funkcja(int i)
{
    return i + 2;
}

class WaznaIPowaznaKlasa
{
public:
    static int jestem_sobie_metoda(int i)
    {
       return i+2;
    }
};

int main()
{
    std::cout<< jestem_sobie_funkcja(5) << '\t';
    std::cout << WaznaIPowaznaKlasa::jestem_sobie_metoda(6) << '\n';
    return 0;
}

using namespace cośtam importuje funkcje, ale nie metody. (A przynajmniej tak mi się wydaje.)

0

No dobra, trochę Javizmami poleciałem :] W Javie statyczne metody to mniej więcej to samo co w C++ globalne funkcje. Chodziło mi właśnie o to.

0

No ale przecież C++ także wspiera statyczne metody obok globalnych funkcji. Więc to nie do końca to samo

0
Wibowit napisał(a):

Problemy powinny generalnie zostać wychwycone przez testy.

To już grozi dygresją i pojechaniem poza główny temat, ale trudno.

Wydaje mi się, że tu są dwie szkoły: Jedna głosi, że unit testy >> statyczne sprawdzanie poprawności przez kompilator, a druga, że jest dokładnie na odwrót.

I tak np. Uncle Bob potępia Kotlin i Swift z tego powodu, że one idą w kierunku wyłapywania błędów w czasie kompilacji kosztem, wg U.Boba, uprzykrzania życia programiście piszącego kod: https://blog.cleancoder.com/uncle-bob/2017/01/11/TheDarkPath.html

A z kolei proponenci tego drugiego podejścia idą w kierunku, że "jeśli się kompiluje, to jest już 90% szans, że jest poprawne" i że to jest właśnie wygodne podejście. (W szczególności ta zaleta jest często podnoszona w przypadku Haskella chyba)

1

w javie, c# czy pythonie nie uzywa sie plikow naglowkowych wiec problem jest marginalny i podnieca tylko review-nazi ;)
przy tworzeniu odpowiednio wyspecjalizowanych klas/modulow wszystko powinno byc wystarczajaco jednoznaczne, jesli istnieje szansa pogubienia sie co jest skad to najprawdopodobniej nasze pliki z kodem sa po prostu za wielkie. ewentualnie przy klejeniu kilku bibliotek w jednym module mozna pomyslec o fully qualified nazwach, w c# mozna sobie fajnie aliasowac typy, w javie po prostu caly/unikalny fragment namespace :(

0

@kmph:
Nadinterpretujesz :) Ja jestem za silnym typowaniem. Trzeba znaleźć jakiś złoty środek między klepaniem testów do najbardziej trywialnych rzeczy, a próbie wepchania wszystkiego co się da do systemu typów. Jeśli chodzi o języki kaczo typowane to w Lispie już z 60 lat temu wymyślono w zasadzie wszystko. Tendencja jest jednak ku statycznemu typowaniu - dla przykładu TypeScript jest popularnym rozszerzeniem JavaScriptu i jego statyczne typowanie jest traktowane jako duże usprawnienie. Skomplikowane statycznie typowane języki to jednak raczej nowość i dlatego dużo jest tarcia (sporów) w tej dziedzinie.

Wracając do tematu: using namespace xxx; w C++ to naprawdę hurtowy import w porównaniu do tych typowych Javowych. W Javie połączenie import paczkaZDużąIlościąKlas.*; z import static paczka.KlasaZMasąStatycznychMetod.* w jednym pliku to raczej rzadkość. Ja jednak w C++ pisałem zbyt mało, by mieć jakieś stanowcze zdanie na ten temat.

1
kmph napisał(a):

Ale jednak przyjęło się, że using namespace cokolwiek dopuszczalne jest tylko i wyłącznie w ciele funkcji; na górze pliku jest niedopuszczalne.

Mam wątpliwości czy „się przyjęło”.
Bawią mnie zwłaszcza przykłady typu hello world w których usilnie stawia się wszędzie te dodatkowe znaczki, w stylu std::cout, std::endl. No ludzie…

A już przy tutorialach z C++11 i dalszych, jest praktycznie gwarantowane że wszędzie będzie std::move zamiast move nawet jeśli u góry widnieje using namespace std… :-)

0

using namespace XXX w C++ nic nie znaczy jeśli nie masz też odpowiednich include wiec jeżeli namespace jest podzielona na kilka plików to możesz dodać tylko jej cześć do globalnego zakresu

1 użytkowników online, w tym zalogowanych: 0, gości: 1