programing

Swift의 매크로?

sourcetip 2021. 1. 14. 23:42
반응형

Swift의 매크로?


Swift는 현재 매크로를 지원합니까, 아니면 향후 지원을 추가 할 계획이 있습니까? 현재 나는 흩어지고 있습니다.

Log.trace(nil, function: __FUNCTION__, file: __FILE__, line: __LINE__)

내 코드의 여러 곳에서.


이 경우 "매크로"매개 변수에 대한 기본값을 추가해야합니다.

Swift 2.2 이상

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 이하

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")

이것이 fatalErrorassert기능이하는 일입니다.

다른 답변에서 이미 언급 한 조건부 컴파일을 제외하고는 다른 매크로가 없습니다.


애플 문서 상태가 :

간단한 매크로를 전역 상수로 선언하고 복잡한 매크로를 함수로 변환합니다.

여전히 # if / # else / # endif를 사용할 수 있습니다.하지만 제 느낌은 매크로 함수를 도입하지 않을 것이라는 것입니다. 언어에는 단순히 필요하지 않습니다.


엑스 코드 7.3 이후 __FILE__ __FUNCTION____LINE__컴파일 시간 상수는 더 좋은-보고되고있다 #file #function#line각각.


lastPathComponent필요 NSURL하므로 위의 코드를 다음과 같이 변경했습니다.

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")

다음은 업데이트 된 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)]"
}

사용 예 :

LogW("Socket connection error: \(error)")

매크로는 사악하지만 때로는 필요합니다. 예를 들어,

struct RegionEntity {
    var id: Int!
}

그리고이 구조체의 인스턴스를 Set에 배치하고 싶습니다. 그래서 나는 그것을 Hashable 프로토콜에 따라야합니다.

extension RegionEntity: Hashable {
    public var hashValue: Int {
        return id
    }
}

public func ==(first: RegionEntity, second: RegionEntity) -> Bool {
    return first.id == second.id
}

큰. 그러나 그러한 구조체가 수십 개 있고 논리가 동일하다면 어떻게 될까요? 아마도 일부 프로토콜을 선언하고 암시 적으로 Hashable에 따를 수 있습니다. 점검 해보자:

protocol Indexable {
    var id: Int! { get }
}

extension Indexable {
    var hashValue: Int {
        return id
    }
}

func ==(first: Indexable, second: Indexable) -> Bool {
    return first.id == second.id
}

음, 작동합니다. 이제 내 구조체를 두 프로토콜에 맞게 수정하겠습니다.

struct RegionEntity: Indexable, Hashable {
    var id: Int!
}

Nope. I can't do that, because Equatable requires == operator with Self and there is no == operator for RegionEntity. Swift forces me to copy-paste confirmation code for each struct and just change the name. With macro I could do that with only one line.


There is way to use macros on swift (but this used in Mixed of objective c and swift)

declare your macros into Project-name-Bridging-Header.h

#define  YOUR_MACRO @"Description"

or create separate header file for macros "macros.h"

import this header "macros.h" in to your Bridging-Header.h file..

now just save your project your macros will came in swift file ..

if you don't wanna object c code on your swift project... just create dummy cocoa touch classes it will create bridging header then use my way...

ReferenceURL : https://stackoverflow.com/questions/24114288/macros-in-swift

반응형