Makra w Swift?
Czy Swift obsługuje obecnie makra, czy też istnieją plany dodania wsparcia w przyszłości? Aktualnie rozrzucam:
Log.trace(nil, function: __FUNCTION__, file: __FILE__, line: __LINE__)
W różnych miejscach mojego kodu. 7 answers
W tym przypadku należy dodać wartość domyślną dla parametrów "makro".
Swift 2.2 i wyższe
func log(message: String,
function: String = #function,
file: String = #file,
line: Int = #line) {
print("Message \"\(message)\" (File: \(file), Function: \(function), Line: \(line))")
}
log("Some message")
Swift 2.1 i niższe
func log(message: String,
function: String = __FUNCTION__,
file: String = __FILE__,
line: Int = __LINE__) {
print("Message \"\(message)\" (File: \(file.lastPathComponent), Function: \(function), Line: \(line))")
}
log("Some message")
Do tego służą funkcje fatalError
i assert
.
Nie ma innych makr poza kompilacją warunkową wspomnianą już w innej odpowiedzi.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-19 07:52:23
Dokumenty Apple stwierdzają, że:
Deklaruje proste makra jako stałe globalne i tłumaczy złożone makra na funkcje.
Nadal można używać # if / # else / # endif - ale mam wrażenie, że nie wprowadzą funkcji makr, język po prostu tego nie potrzebuje.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-09 05:46:47
Od XCode 7.3, the __FILE__
__FUNCTION__
i __LINE__
stałe czasu kompilacji stały się ładniej wyglądające #file
#function
i #line
odpowiednio.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-27 16:01:45
lastPathComponent
potrzebuje NSURL
, więc zmieniłem powyższy kod na ten:
func log(message: String,
function: String = __FUNCTION__,
file: String = __FILE__,
line: Int = __LINE__) {
let url = NSURL(fileURLWithPath: file)
print("Message \"\(message)\" (File: \(url.lastPathComponent ?? "?"), Function: \(function), Line: \(line))")
}
log("some message")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-20 09:38:14
Oto zaktualizowana odpowiedź Swift 2.
func LogW(msg:String, function: String = #function, file: String = #file, line: Int = #line){
print("[WARNING]\(makeTag(function, file: file, line: line)) : \(msg)")
}
private func makeTag(function: String, file: String, line: Int) -> String{
let url = NSURL(fileURLWithPath: file)
let className = url.lastPathComponent ?? file
return "\(className) \(function)[\(line)]"
}
Przykład użycia:
LogW("Socket connection error: \(error)")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-04 23:57:37
Jest sposób na użycie makr w języku swift (ale to używane w połączeniu z objective c i swift)
Zadeklaruj swoje makra do Project-name-Bridging-Header.h
#define YOUR_MACRO @"Description"
Lub utworzyć oddzielny plik nagłówkowy dla makr "macros.h"
Importuj ten nagłówek " makra.h " w Twoim pomostowym nagłówku.plik H..
Teraz po prostu zapisz swój projekt Twoje makra pojawią się w pliku swift ..
Jeśli nie chcesz zgłaszać kodu c w swoim projekcie swift... wystarczy utworzyć atrapę cocoa touch klas to stworzy nagłówek mostkowy, a następnie Użyj mojej drogi...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-14 11:32:28
Makra są złe, ale czasami po prostu ich potrzebujesz. Na przykład Mam
struct RegionEntity {
var id: Int!
}
I chcę umieścić instancje tej struktury na Set. Więc muszę dostosować to do protokołu Hashable.
extension RegionEntity: Hashable {
public var hashValue: Int {
return id
}
}
public func ==(first: RegionEntity, second: RegionEntity) -> Bool {
return first.id == second.id
}
Świetnie. Ale co jeśli mam dziesiątki takich struktur i logika jest taka sama? Może mogę zadeklarować jakiś protokół i dostosować go do Hashable bezwarunkowo. Sprawdźmy:
protocol Indexable {
var id: Int! { get }
}
extension Indexable {
var hashValue: Int {
return id
}
}
func ==(first: Indexable, second: Indexable) -> Bool {
return first.id == second.id
}
To działa. A teraz dostosuję swoją strukturę do obu protokołów:
struct RegionEntity: Indexable, Hashable {
var id: Int!
}
Nie. Nie mogę. to, ponieważ równanie wymaga operatora = = z Self i nie ma operatora == dla RegionEntity.
Swift zmusza mnie do kopiowania i wklejania kodu potwierdzającego dla każdej struktury i po prostu zmiany nazwy. Z makro mogłem to zrobić tylko jedną linią.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-15 22:13:33